ThinkPHP多语言网站需三步:语言包置于lang/zh-cn/、lang/en-us/下且含return[];配置开启lang_switch_on、设lang_list白名单、关闭allow_url_lang;通过中间件在请求初调用Lang::setLang()并存Session切换。

ThinkPHP搭建多语言网站,核心是三件事:语言包放对位置、框架识别到语言、翻译调用前语言已生效。中英文切换不是加个链接就完事,关键在路径规范、配置组合和执行时机——错一处,lang('hello')就原样返回'hello',还不报错。
语言包必须按规范建在 lang/ 目录下
ThinkPHP 只认 lang/{lang-code}/common.php 这种结构,其他路径一律忽略:
- 根目录下新建
lang/文件夹(不是config/lang.php,也不是app/Lang/) - 子目录名全小写、用连字符,如
lang/zh-cn/和lang/en-us/;zh_CN、ZH-CN、en都无效 - 每个子目录里放
common.php,内容必须是 PHP 数组并以return [...];结尾
例如lang/zh-cn/common.php:return ['welcome' => '欢迎使用', 'login' => '登录'];
对应lang/en-us/common.php:return ['welcome' => 'Welcome', 'login' => 'Login']; - Linux 服务器严格区分大小写,路径错一个字母,语言包就静默失效
配置文件要开开关、设白名单、关干扰项
仅开启 lang_switch_on 不够,必须组合配置才能让中英文切换真正可控:
- 在
config/app.php中确认以下几项: -
'lang_switch_on' => true(必开) -
'default_lang' => 'zh-cn'(默认 fallback) -
'lang_list' => ['zh-cn', 'en-us']或'lang_list' => 'zh-cn,en-us'(白名单,不在其中的语言无法加载) -
'allow_url_lang' => false(若用子域名或 Session 切换,必须关掉 URL 参数自动识别,否则?lang=en-us会覆盖你的逻辑)
语言必须在请求最开始就设好
翻译函数 lang() 一调用,语言包就锁定了。如果中间件没提前设置,控制器里再改也晚了:
立即学习“PHP免费学习笔记(深入)”;
- 创建中间件
app/middleware/Lang.php - 在
handle()方法开头就读取用户偏好:$lang = $request->session('lang', 'zh-cn'); - 立即执行:
\think\Lang::setLang($lang); - 把该中间件注册进
app/middleware.php的全局数组:return [\think\middleware\Lang::class, ...]; - 切记:不能在控制器构造函数或操作方法里调
setLang(),那时系统可能已加载验证提示等默认语言文本
前端切换要存 Session 并触发刷新
点击“中文/English”只是改变用户意图,需后端配合持久化并重载上下文:
- 提供切换入口,例如:
<a href="{:url('index/langswitch',['lang'=>'zh-cn'])}">简体中文</a><a href="{:url('index/langswitch',['lang'=>'en-us'])}">English</a> - 在对应控制器方法中校验并保存:
$lang = input('lang');<br>if (in_array($lang, config('lang_list'))) {<br> session('lang', $lang);<br>} - 跳转回原页面(可用
referer()),下次请求中间件就会读到新值并加载对应语言包 - 模板中统一用
{:lang('welcome')}或{__('login')},不拼接 HTML,不硬编码文字



















