ThinkPHP 多语言性能瓶颈在于每次请求重复加载解析语言文件,必须执行 php think build:lang 生成缓存,关闭自动探测,并在控制器预加载语言变量,否则优化无效。

ThinkPHP 多语言慢,根本不在 lang() 函数本身,而在每次请求都重新 require 一堆 PHP 语言文件——解析、执行、合并数组,全量重复。不生成编译缓存,光改配置没用。
必须手动执行 php think build:lang 生成缓存
框架的 lang_cache 配置只是开关,不是“自动缓存”。不运行命令,runtime/lang/ 下压根没文件,缓存逻辑根本不会触发。
- TP6.1+ 执行:
php think build:lang;旧版用php think optimize:lang - 生成后,所有语言包(如
zh-cn.php、zh-cn/admin.php)被合并 + 序列化,存为单个runtime/lang/zh-cn.php - 后续请求直接
include这个文件,跳过全部解析和遍历逻辑 - 修改语言包后必须重跑该命令,缓存不会自动更新
- 确保
runtime/目录可写,且路径在config/app.php中显式指定(避免 NFS 或 Docker 挂载导致写入延迟)
模板里别高频调用 lang()
每个 {:lang('xxx')} 都会触发一次数组查找 + 语言包存在性判断。50 次调用 ≠ 50 次函数开销,而是 50 次键检查 + 可能的 fallback 路径遍历。
- 控制器中统一收集:
$this->assign('i18n', ['welcome' => lang('welcome'), 'submit' => lang('submit')]); - 模板中改用
{$i18n.welcome},零运行时函数调用 - 带参数的动态文本(如
lang('hello', ['name' => $user->name]))保留在控制器处理,不塞进模板 - 关闭模板引擎的隐式语言标签:设
'lang_tag' => false,防止{% lang 'xxx' %}类语法偷偷触发
禁用浏览器语言自动探测
开启 auto_detect_browser 后,每次请求都要解析 $_SERVER['HTTP_ACCEPT_LANGUAGE'],做字符串截取、匹配、降级(zh-CN → zh),还可能触发额外的语言包加载。
立即学习“PHP免费学习笔记(深入)”;
- 在
config/lang.php中设'auto_detect' => false - 改由登录态、URL 参数(如
?lang=zh-cn)或 Cookie 显式控制语言,更可控也更快 - 若必须支持自动探测,至少加一层 APCu 缓存解析结果,避免每次重复处理
真正卡住多语言性能的,从来不是翻译文本本身,而是加载链路里的重复 IO、无索引遍历、未生效的缓存开关。生成缓存、预加载变量、关掉自动探测——这三步做完,TTFB 里那多出来的 80ms 就没了。但只要漏掉 build:lang,其他全白搭。



















