phpEnv中需手动启用gettext扩展,确认PHP版本匹配的php_gettext.dll存在且php.ini中已取消注释extension=php_gettext.dll;Windows下setlocale需用Chinese_China.936等系统支持的locale名,并严格匹配./locale/zh_CN/LC_MESSAGES/messages.mo路径与编码设置,否则_()函数返回原文。

phpEnv 默认不启用 gettext 扩展,必须手动开启并验证路径、编码和 locale 设置是否匹配,否则 _() 函数始终返回原文。
确认 phpEnv 当前 PHP 版本与扩展目录
phpEnv 是 Windows 下的便携式 PHP 环境管理工具,每个 PHP 版本独立存放,gettext 扩展文件(php_gettext.dll)需对应版本。常见错误是复制了旧版 DLL 到新版目录,或路径未加入系统环境变量。
- 打开命令行,进入 phpEnv 安装目录下的当前 PHP 版本子目录(如
phpenv\versions\8.2.12\) - 执行
php -v确认版本,再运行php -m | findstr gettext查看是否已加载 - 若无输出,检查
ext/目录下是否存在php_gettext.dll;不存在则需从同版本官方 PHP zip 包中提取(不要混用 VC15/VC16 或 TS/NTS 版本) - 确保
php.ini中该行未被注释:extension=php_gettext.dll
修改 php.ini 并重启 phpEnv 内置服务
phpEnv 的配置文件位于对应 PHP 版本目录下的 php.ini,不是系统级配置。改错位置会导致 phpinfo() 里看不到 gettext 模块。
- 用记事本或 VS Code 打开
phpenv\versions\8.2.12\php.ini - 搜索
php_gettext.dll,取消注释并确认路径正确(默认就是extension=php_gettext.dll,无需写绝对路径) - 在文件末尾添加一行:
gettext.default_domain = messages(可选,但能减少代码中重复调用textdomain()) - 保存后,在 phpEnv 控制面板中「重启 PHP」或关闭再重开服务窗口
- 新建
test.php,内容为<?php phpinfo(); ?>,浏览器访问,搜索 “gettext” 确认模块已加载
Windows 下 setlocale 失败的典型原因与绕过方案
Windows 对 locale 名称支持有限,setlocale(LC_ALL, 'zh_CN.UTF-8') 极大概率返回 false,导致 gettext 完全不工作——这不是 PHP 错误,而是系统本身不提供该 locale。
立即学习“PHP免费学习笔记(深入)”;
- 先测试可用 locale:
var_dump(setlocale(LC_ALL, 'Chinese_China.936', 'chinese', ''));
常见有效值包括Chinese_China.936(简体中文 GBK)、English_United States.1252 - 必须配合
putenv("LANG=zh_CN")和bind_textdomain_codeset('messages', 'UTF-8')强制指定 MO 文件编码,否则中文显示为乱码 - MO 文件路径必须用正斜杠或双反斜杠:
bindtextdomain('messages', './locale');,不能写成'.\locale' - 推荐最小初始化代码段:
putenv('LANG=zh_CN');
setlocale(LC_ALL, 'Chinese_China.936');
bindtextdomain('messages', './locale');
bind_textdomain_codeset('messages', 'UTF-8');
textdomain('messages');
PO 文件编译与 MO 文件存放结构
phpEnv 运行的是 Windows CLI 或 Apache,但 msgfmt 命令默认不可用。你无法直接在 Windows 上用原生命令行生成 MO 文件,必须借助 Poedit 或预编译好再放入项目。
- 下载安装 Poedit(免费版足够),打开你的
messages.po,保存即自动生成同名.mo文件 - MO 文件必须放在严格符合 GNU 标准的路径下:
./locale/zh_CN/LC_MESSAGES/messages.mo,其中zh_CN必须与setlocale中使用的 locale 基名一致(不含.UTF-8后缀) -
messages.po中第一行需包含"Content-Type: text/plain; charset=UTF-8\n",否则 Poedit 可能误判编码 - 测试时删掉
./locale/zh_CN/LC_MESSAGES/下除messages.mo外所有文件,避免 gettext 加载到残留的旧版本
最容易被忽略的是:Windows 系统 locale 名称和 GNU gettext 路径命名规则之间没有自动映射关系,zh_CN 在 PHP 里要写成 Chinese_China.936,但在文件夹名里仍叫 zh_CN——这个割裂必须手动对齐,否则 gettext 查不到 MO 文件。



















