ThinkPHP语言包不支持热更新,因默认启用缓存且早期静态加载;修改后需手动清缓存、调用Lang::load()或Lang::clear()并配合OPcache重置及Swoole进程重启。

ThinkPHP 语言包本身不支持“热更新”——改完 lang/zh-cn.php 文件后,下次请求仍会读取旧缓存,除非手动清空或重启服务。这不是 bug,是设计使然:语言包在请求生命周期早期加载并静态缓存,避免重复 IO。
为什么改了语言文件没生效?
常见现象是修改了 lang/en-us.php 里的文案,刷新页面还是旧内容。原因有三:
- 框架默认启用语言包缓存(
runtime/lang/下生成 PHP 编译后文件),不随源文件变化自动重建 -
Lang::get()读的是内存中已加载的数组副本,不是实时 require 源文件 - 开发时若开了 OPcache,还可能缓存了
lang/*.php的字节码,双重锁定
强制重载语言包的实操方式
无需重启 PHP-FPM 或 Swoole,只需在调试阶段主动触发重新加载:
- 在控制器或中间件里调用
Lang::load($lang),传入目标语言标识(如'en-us'),它会清空该语言缓存并重新解析文件 - 更彻底的做法:
Lang::clear()清空全部语言缓存,再调用Lang::setLocale($lang)切换 - 注意顺序:
Lang::setLocale()必须在Lang::load()之后调用,否则新内容不会被当前请求使用
开发环境一键热更脚本
把下面这段代码临时加到某个调试路由(如 /debug/lang-reload)里,方便前端改完语言包立刻验证:
立即学习“PHP免费学习笔记(深入)”;
if (app()->isDebug()) {
Lang::clear();
Lang::setLocale(Lang::getLangSet()); // 保持当前语言
echo 'Lang reloaded';
}
配合 IDE 的“保存即刷新”插件,可实现接近热更的体验。但别在生产环境暴露此接口。
OPcache 和 runtime 缓存必须同步清理
仅改 PHP 文件还不够。两个地方要一起动:
- 删掉
runtime/lang/目录下所有文件(这是 ThinkPHP 自己生成的语言缓存) - 执行
opcache_reset()(需在 php.ini 中允许,且只对 CLI 或 Web 请求有效);或者更稳妥:sudo systemctl reload php*-fpm - 如果用了 Swoole 常驻模式,
php think swoole:reload是必须的,因为语言包在 Worker 启动时就已加载进内存
最易忽略的是:Swoole 模式下,即使清了 runtime/lang 并调用了 Lang::clear(),老 Worker 进程仍持有旧数据——必须 reload 进程才能真正生效。



















