lang('welcome')只显示键名说明语言包未加载成功,主因是语言包路径错误或中间件LoadLangPack未启用,需先在控制器中验证Lang::get()是否正常工作。

模板里写 lang('welcome') 不出翻译、只显示键名,说明语言包根本没加载成功,不是语法或缓存问题。
Lang::get() 在模板中失效的常见原因
ThinkPHP6 模板引擎本身不解析 lang() 函数调用,它只是原样输出——真正起作用的是 PHP 解析器在执行模板时运行该函数。所以“不解析”本质是函数执行失败或返回了键名本身。
- 最常见:语言包路径错误,
app/lang/zh-cn.php不存在或命名是zh_CN.php(框架会转成小写连字符,但文件系统大小写敏感,Linux 下zh-CN.php和zh-cn.php是两个文件) - 次常见:中间件未启用,
think\middleware\LoadLangPack没加进app/middleware.php,导致整个语言包加载流程被跳过 - 容易忽略:模板被缓存且缓存未更新,但更大概率是首次访问就失效,说明不是缓存问题而是加载链断裂
- 危险信号:如果
Lang::get('welcome')在控制器里也返回welcome,那基本可确认语言包完全没加载;如果控制器里正常、模板里异常,则可能是模板编译后未重新生成(删runtime/view/目录即可)
检查 Lang::get() 是否真能工作
别信模板,先在控制器里硬测:
public function index()
{
dump(Lang::getLangSet()); // 应输出 'zh-cn' 或 'en-us'
dump(lang('welcome')); // 应输出翻译值,不是 'welcome'
dump(file_exists(app()->getLangPath() . 'zh-cn.php')); // 确认路径存在
return view();
}
- 如果
Lang::getLangSet()返回空或default_lang配置值但没变,说明语言侦测失败 → 检查config/lang.php中'detect_var' => 'lang'和'allow_lang_list'是否配置,以及请求是否带?lang=zh-cn - 如果
lang('welcome')返回键名,但文件存在 → 检查zh-cn.php是否以return ['welcome' => '欢迎'];形式返回,开头不能有 BOM、空格、echo或 UTF-8 签名 - 如果
file_exists()返回false→ 路径拼错了,确认app()->getLangPath()输出的是/var/www/html/app/lang/这类绝对路径,不是相对路径
模板中 lang() 不生效的修复动作
确认函数本身可用后,再聚焦模板场景:
立即学习“PHP免费学习笔记(深入)”;
- 确保模板文件后缀是
.php(不是.html),否则不会被 PHP 解析器执行 - 避免在模板里写
<?php lang('welcome'); ?>却不echo—— 正确写法是= lang('welcome') ?>或<?php echo lang('welcome'); ?> - 不要在模板里调用
Lang::setLocale()后立刻用lang(),因为语言包已加载完毕,setLocale()不会触发重载;如需动态切语言,应在控制器或中间件里完成 - 多应用模式下,模板语言包路径应为
app/应用名/lang/zh-cn.php,不是app/lang/;若用app/index/lang/zh-cn.php,则需在config/lang.php中设置'path' => app_path('index/lang')
真正卡住的地方往往不是语法,而是语言包路径和中间件注册这两个硬性开关——漏一个,整个链就断了。别调模板缓存,先让 lang() 在控制器里跑通,再看模板。



















