thinkphp语言包修改后页面未变,是因lang类内存缓存及opcache未刷新所致;需在lang::setlang()后调用lang::load()强制重载,或重启php-fpm、重置opcache。

多语言包改了但页面没变?不是缓存没清,是语言包根本没重载
ThinkPHP 的语言包是 PHP 文件,加载后会缓存到内存(Lang 类内部静态数组),不是靠 runtime 缓存目录控制的。你删了 runtime/lang/ 或执行 php think clear,对已加载的语言翻译完全无效。
常见错误现象:
-
lang('hello')仍返回旧翻译,哪怕lang/zh-cn/common.php已改 - 切换语言后部分页面生效、部分不生效,尤其跨模块时
实操建议:
- 开发阶段,在中间件或控制器开头加
\think\Lang::load();强制重载当前语言包(注意:必须在Lang::setLang()之后调用) - 上线前别依赖“改完就生效”,应重启 PHP-FPM 或重载 OPCache(
opcache_reset()),否则 PHP 缓存了旧的common.php字节码 - 如果用了多分组(如
user.php、admin.php),需显式调用Lang::load('user', 'zh-cn'),不能只靠common.php
lang() 函数不生效?检查 lang/ 目录结构和文件名大小写
ThinkPHP 对语言包路径极其敏感,错一个字符、大小写不对、目录层级偏差,都会静默失败——不报错,lang() 直接返回原 key。
正确结构必须是:
- 根目录下有
lang/(不是config/lang.php,也不是app/lang/) -
lang/zh-cn/(小写、连字符,zh_CN或ZH-CN都不行) -
lang/zh-cn/common.php必须以return ['hello' => '你好'];结尾,不能是 JSON、不能带 BOM、不能有输出
容易踩的坑:
- Linux 服务器上
lang/ZH-CN/和lang/zh-cn/是两个目录,前者完全不会被识别 - IDE 自动保存为 UTF-8 with BOM,导致
common.php开头有不可见字符,return前有输出 →lang()失败 - 把语言包放在
app/lang/下却没开启模块级语言支持(需配置'allow_group' => true)
动态切换语言后翻译还是默认值?Lang::setLang() 调用时机错了
Lang::setLang('en-us') 必须在任何 lang() 调用之前执行,且只能执行一次。一旦翻译函数触发过,后续再设语言也无效。
典型错误写法:
- 在控制器
__construct()里调用 —— 此时中间件还没跑完,Lang中间件可能已经加载了默认语言包 - 在模板里写
{:lang('hello')}前才调Lang::setLang()—— 模板编译时语言环境已锁定 - 在 AJAX 接口里单独设语言,但没清前端缓存,浏览器发的是旧 Accept-Language
正确做法:
- 在全局中间件(如
app/middleware.php)中最早位置调用Lang::setLang($lang) - 从 Session 或 Cookie 读取语言偏好,不要依赖
$_GET['lang'](除非你手动解析并校验) - 切换语言后,用
header('Location: ' . $_SERVER['REQUEST_URI']);刷新整页,避免 JS 渲染残留
为什么线上环境多语言突然失效?OPCache 和部署脚本惹的祸
本地改了 common.php 看起来 OK,一上线就回退——大概率是 OPCache 没刷新,或者 CI/CD 脚本删 runtime 时误删了语言包缓存标记。
关键点:
- PHP CLI 和 Web SAPI 的 OPCache 是分开的,
opcache_reset()在命令行里运行无效,得在 Web 环境中调用(比如加个 admin 接口) - 某些部署脚本执行
php think clear -f时,会顺手删掉runtime/lang/下的 PHP 编译缓存文件(如果启用了lang_cache选项),导致首次请求语言包加载失败 - TP6.3+ 默认启用语言包编译缓存(
lang_cache),路径在runtime/lang/,它和runtime/cache/是两套机制,php think clear不清它
上线前务必确认:
- 检查
config/lang.php中'lang_cache' => false(开发期关掉更可控) - CI/CD 中清除缓存的步骤,要排除
runtime/lang/目录 - 用
php -r "var_dump(opcache_get_status()['scripts']);"查看语言包是否还在 OPCache 中
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











