PHP8线程安全版本需严格匹配达梦驱动文件名,如php80ts_dm.dll与pdots_dm.dll必须与PHP小版本、架构(x64/x86)、线程模型(TS)完全一致;验证需通过php -v确认ZTS,php --ini定位php.ini并添加extension=php80ts_dm和extension=pdots_dm,复制dmdpi.dll至系统目录,ThinkPHP6配置type='dm'、hostport='5236'、charset='utf8',且须配置ANSI编码的dm_svc.conf启用CHAR_CODE=(PG_UTF8),并自定义Dm Builder类适配rownum分页语法。

PHP8线程安全版本必须匹配达梦驱动文件名
达梦PHP驱动不是“装上就能用”,php80ts_dm.dll 和 pdots_dm.dll 必须与你实际运行的PHP小版本、架构(x64/x86)、线程模型(TS)完全一致。常见错误是看到“PHP8”就复制 php81ts_dm.dll 到 PHP 8.0.25 TS 环境里,结果 Apache 启动失败或 php -m 报 Unable to start DM module。
验证方式很简单:
- 运行
php -v看到类似PHP 8.0.25 (cli) (built: ... ) ( ZTS )—— 表明是 TS 版 - 运行
php --ini找到真实生效的php.ini路径 - 在该
php.ini中添加两行:extension=php80ts_dm和extension=pdots_dm(不带 .dll 后缀) - 重启 PHPStudy 服务后,访问
phpinfo()页面搜索dm或PDO Driver for DM
若仍失败,把达梦安装目录 bin/ 下的 dmdpi.dll 复制到 C:\Windows\System32(64位系统)或 SysWOW64(32位 PHP),这是 Windows 下 DLL 依赖未解析的典型表现。
ThinkPHP6 的 database.php 配置要绕开 MySQL 惯性思维
达梦不是 MySQL,type 值填 'dm' 是前提,但更关键的是几个易错参数:
立即学习“PHP免费学习笔记(深入)”;
-
hostport必须显式写成'5236',不能省略或写成'';达梦默认端口虽是 5236,但 ThinkPHP 的 PDO 构造器不自动 fallback -
charset推荐设为'utf8',不是'utf8mb4'—— 达梦 V8 对 utf8mb4 支持不完整,否则插入 emoji 或某些生僻字会报错Invalid character string format -
prefix若为空字符串'',必须确认建表时没加双引号;达梦对大小写敏感,默认创建的表名是大写,think_user和THINK_USER是两个对象 - 连接测试时,先用
dm_connect("127.0.0.1:5236", "SYSDBA", "xxx")单独跑通,再进 TP6,避免把连接问题和 ORM 解析问题混在一起
中文乱码和字符集问题出在 dm_svc.conf,不是 php.ini
即使 php.ini 设了 default_charset = "UTF-8",TP6 查询返回中文仍是问号或方块,大概率是达梦客户端层的字符映射没对齐。这个配置不在 PHP,而在操作系统级的 dm_svc.conf 文件。
Windows 下该文件需放在 C:\Windows\ 目录;Linux 下放在 /etc/。内容至少包含:
CHAR_CODE=(PG_UTF8) LANGUAGE=(cn)
注意两点:
-
PG_UTF8是达梦内部标识,不是 PostgreSQL 协议 —— 它表示“兼容 PostgreSQL 的 UTF8 编码行为”,这是达梦适配 PHP PDO 的关键开关 - 该文件必须是 ANSI 编码(非 UTF-8),否则达梦驱动读取失败,静默忽略配置
- 改完后无需重启 PHP,但需重启 Apache 或 Nginx 进程,让新环境变量生效
Dm Builder 类缺失会导致分页、子查询直接报错
ThinkPHP6 默认没有达梦专用的 SQL 构建器,limit、order by、union 等语句生成的 SQL 会沿用 MySQL 语法,而达梦用的是 rownum 伪列嵌套,不重写构建逻辑,paginate() 会返回空结果或 ORA-00904: "ROWNUM" invalid identifier 类错误。
必须手动补全两个类:
- 在
app/common/db/builder/Dm.php(路径可自定义)中新建Builder类,继承think\db\Builder,重写$selectSql模板和parseLimit方法 - 在
app/common/db/connection/Dm.php中新建Connection类,指定builder为刚写的 Dm Builder - 最后在
config/database.php的connections.dm配置项里加上:'builder' => \app\common\db\builder\Dm::class
这一步没法跳过,哪怕只是简单 select * from user 也不影响,一旦涉及分页、排序、关联查询,就会暴露。



















