think_lang cookie 键名必须准确,lang 中间件需显式注册且顺序在 sessioninit 后、路由前;必须用 cookie() 函数写入,语言包路径须为 lang/{lang}/(如 lang/zh-cn/),url 参数 ?lang= 优先级高于 cookie。

think_lang 这个 Cookie 键名必须用对,否则 Lang 中间件完全不触发语言切换——它不报错、不警告,只是静默跳过。
Lang 中间件必须显式启用且顺序正确
ThinkPHP 的多语言自动识别不是开箱即用的,默认 Lang 中间件根本没注册。你在 app/middleware.php 里找不到 think\middleware\Lang,就等于没配。
中间件执行顺序直接影响能否读到 Cookie:
- 必须在
SessionInit之后(否则$_COOKIE可能未初始化) - 必须在路由调度之前(否则
Lang::detect()拿不到请求上下文) - 如果用了多应用模式,每个应用的
middleware.php都得单独加这一行
cookie('think_lang', $lang) 是唯一推荐的写法
别手写 setcookie(),也别用 $_COOKIE['think_lang'] = $lang 赋值——前者容易因输出提前失败,后者只改当前数组,浏览器根本收不到。
ThinkPHP 的 cookie() 函数会自动处理加密、前缀、路径和域名等细节:
- 默认路径是
'/',全站有效 - 默认域名是当前 host,跨子域需手动配置
domain选项 - 值会自动加密(除非关了
cookie.encrypt配置) - 要立即生效并持久化,就得调这个函数:
cookie('think_lang', 'zh-cn')
语言包路径和文件结构必须严格匹配
Lang 中间件加载语言包时,只认 lang/{lang}/ 这个目录结构,比如 lang/zh-cn/ 或 lang/en-us/,而不是靠配置文件里的别名或文件名推断。
常见静默失败点:
-
lang/zh-CN/和lang/zh-cn/被当成两个不同语言(大小写敏感) -
lang/zh-cn.php放错位置,Lang 中间件不会扫描根目录下的单文件 - 缺某个语言包里的
common.php,Lang::get('user.name')就返回空,不提示缺文件 - Cookie 值是
en-us,但目录只有en_US,加载失败
URL 参数 ?lang=en 优先级高于 Cookie
只要 lang_switch_on 设为 true(默认就是),系统就会按这个顺序检测语言来源:
- 先看 GET 参数
lang(如/index?lang=ja-jp) - 再查 Cookie
think_lang - 最后 fallback 到配置的
default_lang
这意味着:你刚用 cookie('think_lang', 'fr-fr') 写完,又访问带 ?lang=de-de 的链接,当前请求语言就是德语——但 Cookie 不会因此被覆盖。下次不带参数访问,才回到法语。
这种“一次性的 URL 切换”容易让人误以为 Cookie 失效,其实只是优先级规则在起作用。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











