ThinkPHP6语言白名单通过config/lang.php中allow_lang_list配置控制合法语言标识,仅允许列表内小写短横线格式(如zh-cn)的语言生效,非法参数自动回退default_lang;需配合中间件校验、分应用配置及检查大小写与配置位置。

ThinkPHP6 的语言白名单不是独立配置项,而是通过 config/lang.php 中的 allow_lang_list 选项来控制哪些语言标识是合法、可被系统接受和切换的。它直接决定语言侦测、手动设置或 URL 切换时的有效范围,防止非法语言参数(如 lang=../../etc/passwd)引发路径遍历或加载失败。
核心作用:
只允许列表内的语言标识生效,其余一律回退到 default_lang,不报错也不加载对应语言包。
一、在 config/lang.php 中定义白名单
确保该文件存在且返回数组,关键配置如下:
return [
'default_lang' => 'zh-cn',
'allow_lang_list'=> ['zh-cn', 'en-us', 'ja-jp'], // ✅ 小写短横线格式,必须显式列出
'detect_var' => 'lang',
'use_cookie' => true,
'cookie_var' => 'think_lang',
];
-
allow_lang_list是语言白名单本身,值必须是小写、用短横线连接的标准 locale 格式(如zh-cn,不能是zh_CN、zh或Chinese); - 所有语言切换逻辑(GET 参数、Cookie、Header、手动
Lang::setLocale())都会校验该数组; - 若用户传入
?lang=fr-fr但未在白名单中,系统将忽略并使用default_lang。
二、配合中间件与调用逻辑做二次校验(推荐)
仅靠配置不够安全,尤其在手动切换场景(如点击语言按钮)。应在控制器或中间件中主动校验输入:
use think\Lang;
public function switch($lang)
{
// ✅ 强制校验是否在白名单内
$allowed = config('lang.allow_lang_list', ['zh-cn']);
if (!in_array($lang, $allowed)) {
$lang = config('lang.default_lang', 'zh-cn');
}
// ✅ 设置并持久化
Lang::setLocale($lang);
cookie('think_lang', $lang, 3600 * 24 * 30);
return redirect()->back();
}
注意:
Lang::setLocale()不会自动校验白名单,必须你自己in_array()判断。
三、多应用模式下需分应用配置白名单
如果项目含多个应用(如 app/api/ 和 app/home/),每个应用的 config/lang.php 都要单独设置 allow_lang_list:
-
app/api/config/lang.php白名单可为['en-us'](仅 API 返回英文); -
app/home/config/lang.php白名单可为['zh-cn', 'en-us'](前台支持中英切换);
系统加载语言包时,优先读取当前应用下的配置,不会跨应用混用。
四、常见失效原因与检查点
- ❌ 白名单写了
zh_CN或zh→ 改为zh-cn; - ❌
allow_lang_list写在config/app.php或其他配置文件里 → 必须在config/lang.php; - ❌ 中间件
LoadLangPack未启用 → 导致语言包根本不加载,白名单形同虚设; - ❌ 前端传参
?lang=ZH-CN(大写)→ ThinkPHP 内部会转为小写比对,但建议前端也统一发小写,避免歧义。
不复杂但容易忽略。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











