发布于2026-07-08 阅读(0)
扫一扫,手机访问
### lang/ 目录里哪些文件会被加载?
ThinkPHP 严格按 `lang/{lang}/` 的路径结构加载,而且只加载当前请求语言标识对应的目录下的 PHP 文件(比如 `common.php`、`admin.php`)。不过,这里有几个容易被忽略的细节:
* 只要 `lang/` 下存在某个语言子目录(比如 `lang/pt-br/`),即使该语言从未被请求过,它也不会被自动清理或忽略——它只是“闲置”而已。但闲置不等于没影响:它占磁盘空间、拖慢 IDE 索引,还会干扰团队协作。
* 在模块化项目中,如果某个模块的 `lang/` 目录下有 `zh-cn/user.php`,而应用层 `lang/zh-cn/` 下没有同名文件,框架会加载模块级的文件。反过来,如果应用层有同名文件,模块级的文件会被覆盖。这种隐式覆盖很容易导致翻译漏配,而且没有任何提示。
* 大小写敏感是个大坑。在 Linux 服务器上,`lang/ZH-CN/` 和 `lang/zh-cn/` 是两个完全不同的目录,前者完全无效,但不会报错,只会静默跳过。
### 怎么安全删掉不用的语言包?
这事儿不能靠“猜”或者“看着不用就删”,得结合实际流量和配置交叉验证:
1. 检查 `config/app.php` 中的 `'lang_list' => ['zh-cn', 'en-us']`——这是白名单,只允许切换列表里的语言。不在这个目录里的(比如 `lang/ja-jp/`)可以直接删除。
2. 翻翻 Nginx 或 Apache 的日志,过滤 `?lang=` 或路由路径包含 `/zh-hans/` 的请求,确认过去 90 天内真实触发过的语言码。
3. 检查 Session 或 Cookie 中是否存过非白名单的语言(比如 `$_COOKIE['think_lang'] === 'fr-fr'`)。如果有,说明前端或旧逻辑曾支持过,得先确认废弃后再删。
4. 删之前,用 `grep -r "fr-fr" app/ --include="*.php"` 扫一遍代码,确认没有硬编码调用 `Lang::setLang('fr-fr')` 或类似的逻辑。
### `lang()` 调用本身也会“增肥”
模板里每多一个 `{:lang('submit')}`,就多一次数组键查找加上语言包存在性判断。在高频页面(比如首页、商品列表)里堆几十个,单次耗时虽然是毫秒级的,但叠加起来就相当可观了:
* 静态文本尽量合并。把 `lang('user_name') . lang('colon') . lang('user_email')` 改成 `lang('user_info_line')`,能减少调用次数。
* 避免在循环里调 `lang()`。比如商品列表每行都调 `lang('in_stock')`,正确的做法是提前在控制器里把值赋给变量,再传入模板。
* 禁用模板引擎的自动语言标签解析(设置 `'lang_tag' => false`),防止 `{__('key')}` 这类写法隐式触发额外的翻译逻辑。
### `runtime/lang/` 缓存文件也要定期清理
开启 `lang_cache` 后,框架会把合并后的语言包序列化进 `runtime/lang/zh-cn.php` 这类文件。但这些缓存不会自动失效:
* 你删了 `lang/zh-cn/admin.php`,但 `runtime/lang/zh-cn.php` 里还存着旧内容,后续请求仍然会加载它,导致“删了等于没删”。
* 上线新语言包后,务必手动清空 `runtime/lang/` 目录,否则缓存不更新,翻译也不会生效。
* 在 CI/CD 流程中,建议加一步 `rm -rf runtime/lang/*`,避免缓存残留引发线上问题。
最容易被忽略的点:语言包里的 BOM 头。如果用 Windows 编辑器保存 `zh-cn/common.php` 时带了 UTF-8 BOM,PHP 解析时可能会报 `Cannot declare class` 错误,或者静默失败——不是语言包没加载,而是根本就没执行成功,连错误日志都不留。删之前,先用 `file -i lang/zh-cn/common.php` 检查编码,确保是 `utf-8` 无 BOM。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8