php_gettext.dll 加载需同时满足:扩展启用、架构匹配、libintl.dll 存在且版本≥0.19、路径正确;gettext 初始化须严格按 setlocale→bindtextdomain→textdomain 顺序执行,并确保 mo 文件路径、命名、编码符合 gnu 规范。

确认 php_gettext.dll 是否真被加载
很多问题卡在「php.ini 里解注释了 extension=php_gettext.dll,但实际没生效」。XAMPP 编译时默认不启用 gettext,即使配置写对,缺依赖、架构错、路径错都会静默失败。
打开 http://localhost/dashboard/phpinfo.php,搜索 gettext,必须同时看到:
gettext support => enabled- 函数列表里有
gettext、dgettext、bindtextdomain等
若没出现,别改代码——先查错误日志:xampp\apache\logs\error.log 或 php_error_log,看是否有类似:
PHP Warning: PHP Startup: Unable to load dynamic library 'php_gettext.dll'
Windows 下特别注意:php_gettext.dll 必须和你的 XAMPP 架构严格匹配(x86 版配 x86 DLL,x64 版配 x64 DLL),且不能单独存在。
补全 libintl.dll 并确保路径正确
XAMPP 自带的 php_gettext.dll 强依赖 libintl.dll,但官方包通常不附带它,或附带的是旧版(如 0.17),而 PHP 8.1+ 需要 0.19+ 才能正常调用 bindtextdomain()——否则返回 false 且无报错。
实操建议:
XAMPP 8.0.30 是一款免费、开源的跨平台 Web 服务器集成包,专为快速搭建本地 PHP 开发环境而设计。该版本核心组件包括:Apache 2.4.56、MySQL 8.0.33、PHP 8.0.30、phpMyAdmin 5.2.1 等。它支持 Windows、Linux 和 macOS 系统,可让开发者在个人电脑上轻松模拟服务器环境,无需复杂配置即可运行 WordPress、Thin
- 从 mlocati/gettext-windows 下载匹配你 PHP 架构(x86/x64)和版本的
libintl-2.dll - 重命名为
libintl.dll,放进xampp\php\目录(和php_gettext.dll同级) - 检查
php.ini中extension_dir指向正确路径,例如:extension_dir = "C:\xampp\php\ext" - 重启 Apache 后,运行
var_dump(PHP_BINDIR)确认 PHP 运行时能读到该目录 - 再试
var_dump(bindtextdomain('messages', 'C:/your/locale/path')),返回非false才算真正就绪
setlocale / bindtextdomain / textdomain 三步缺一不可
gettext 不是“设个路径就能翻”,它严格遵循 GNU 流程:漏掉任意一步,_() 就只返回原文,不是 bug,是设计如此。
典型初始化顺序(必须按顺序执行):
-
setlocale(LC_MESSAGES, 'zh_CN.UTF-8'):Windows 下常用Chinese_China.936或zh_CN,可用var_dump(setlocale(LC_ALL, 0))查当前系统支持的 locale 名 -
bindtextdomain('messages', './locale'):第二个参数必须是绝对路径(推荐用realpath()),且目录结构必须为./locale/zh_CN/LC_MESSAGES/messages.mo -
textdomain('messages'):设置默认域,之后_()才会查这个域
额外建议加一行:bind_textdomain_codeset('messages', 'UTF-8'),避免 MO 文件编码解析错乱。
.mo 文件路径、命名与编码必须严守 GNU 规范
哪怕扩展加载成功、初始化也完整,_() 仍返回原文?大概率是 MO 文件没放对位置或不符合规范。
关键约束:
- MO 文件必须放在
locale/{locale_name}/LC_MESSAGES/{domain}.mo,例如:locale/zh_CN/LC_MESSAGES/messages.mo -
{locale_name}必须和setlocale()第二个参数一致(大小写、下划线、点号都要对) - PO 文件编译时需用 UTF-8 编码保存,且 PO 头部明确声明:
"Content-Type: text/plain; charset=UTF-8\n" - 用
msgfmt messages.po -o messages.mo编译,不要手动改后缀,也不要依赖 IDE 自带编译器(部分会丢 plural forms)
最容易被忽略的是 locale 名称和系统实际支持的不一致——比如 Windows 没装中文语言包,却硬写 zh_CN.UTF-8,setlocale() 会静默失败并返回 false,后续所有 gettext 调用都无效。










