thinkphp实现域名语言切换的关键是在中间件handle()开头手动绑定域名与语言码并关闭allow_url_lang,否则验证提示和模板仍为默认语言;需严格遵循lang/en-us/common.php路径规范,且中间件须注册于session之后、路由之前。

ThinkPHP 用 en.example.com 和 cn.example.com 实现语言切换,关键不是靠自动识别,而是手动在请求最开始绑定域名与语言码,并确保语言包加载时机早于任何翻译调用。否则页面文字不会变,验证提示、模板渲染都还是默认语言。
一、先关掉 URL 参数干扰
默认情况下,ThinkPHP 会优先读取 ?lang=en-us 这类参数,导致访问 en.example.com 却显示中文。必须主动关闭这个机制:
- 打开
config/app.php - 设置
'allow_url_lang' => false - 同时确认
'lang_switch_on' => true已开启 - 删掉或注释掉
'lang_detect_var' => 'lang'(除非你后续要保留参数切换)
二、建好标准语言包结构
语言包路径和命名必须严格匹配,否则静默失效:
- 在项目根目录新建
lang/文件夹 - 子目录名全小写、带短横线:
lang/en-us/、lang/zh-cn/(ZH-CN或zh_CN都不行) - 每个子目录下放
common.php,内容为 PHP 数组:return ['hello' => 'Hello']; - Linux 服务器注意大小写敏感,本地测试也建议统一用小写路径
三、用中间件提前绑定域名与语言
不能等进控制器才设语言——那时验证器、模板、系统提示已加载完毕。必须在中间件 handle() 第一行就执行:
- 创建中间件
app\common\middleware\Lang.php - 在
handle()开头提取纯净域名:$host = parse_url($_SERVER['HTTP_HOST'], PHP_URL_HOST); - 读取配置映射(比如
config/lang_domains.php):return ['en.example.com' => 'en-us', 'cn.example.com' => 'zh-cn']; - 查不到时 fallback 到默认语言:
$lang = $langMap[$host] ?? config('app.default_lang'); - 立即调用:
\think\Lang::setLang($lang); - 把该中间件注册到
app/middleware.php全局队列中,且排在 Session 初始化之后、路由之前
四、Web 服务器要正确传递 Host 头
如果 Nginx 或 Apache 没把原始域名传进来,$_SERVER['HTTP_HOST'] 就是空或错的:
- Nginx 配置里确保有:
proxy_set_header Host $host;(反向代理场景)
或直接用server_name绑定多个域名 - Apache 确保
.htaccess在public/目录,且AllowOverride All已启用 - 本地调试时注意端口问题,
localhost:8080会被当完整 host,要用parse_url提取主机名
不复杂但容易忽略:域名切换本质是“早一步决定语言”,而不是“换一个配置再重载”。只要中间件第一行设对,后面所有 lang()、验证提示、模板翻译都会自动生效。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











