thinkphp多语言与队列完全正交,不可混配;多语言需在任务handle()中手动调用lang::set()初始化,语言包必须严格置于lang/zh-cn/common.php等小写路径下,cli环境下不自动加载语言环境。

ThinkPHP 多语言和队列是两个独立模块,不能也不需要“配在一起”。所谓“多语言配队列”,本质是混淆了职责边界:语言包控制文案输出,队列处理异步任务,二者无直接耦合逻辑。强行混合配置只会导致语言不生效、任务执行错乱或日志里满屏 Lang not found。
多语言文件放错位置,队列任务里就看不到翻译
队列任务类(如 app/job/SendEmail.php)在 CLI 模式下运行,不走 HTTP 请求生命周期,lang() 函数默认不会自动加载语言包。
- 语言包必须放在
lang/zh-cn/common.php这类固定路径下,且目录名严格小写(zh-cn≠ZH-CN) - CLI 环境下不会自动读取浏览器
Accept-Language,必须手动指定语言:lang::set('zh-cn') - 如果在任务类的
handle()方法开头漏掉这句,lang('welcome')就永远返回键名本身
队列驱动选 sync 时,多语言看似正常,其实是假象
'default' => 'sync' 表示任务同步执行(即立刻调用 handle()),此时仍处于当前请求上下文,语言环境可能被控制器提前设置过。但一旦切到 redis 或 database 驱动,消费者进程重启后语言状态清空,问题立刻暴露。
-
sync驱动只适合开发调试,上线必须换真实驱动 - 不要依赖“当前请求的语言设置会透传到队列任务”——它根本不会
- 每个队列任务类都应自主管理语言:在
handle()开头显式调用lang::set($lang),$lang可从任务数据中带入
伪静态路由对队列完全无影响,但会影响语言自动探测
ThinkPHP 的伪静态(如 domain.com/zh-cn/user/login)靠 URL 路径前缀触发语言切换,这仅在 HTTP 请求中由中间件完成。队列消费者是常驻 CLI 进程,不解析 URL,也不加载路由规则。
- 伪静态配置写在
config/route.php或config/app.php的url_common等项,和queue.php完全无关 - 如果你在队列任务里硬编码
url()生成链接,又依赖伪静态格式,记得手动拼接语言前缀:url('user/profile', [], true, 'https://example.com/zh-cn') - 别在
handle()里调用request()->lang()——CLI 下这个对象没有语言字段
真正要操心的,是任务数据里是否携带了语言标识、任务类是否主动初始化语言环境、以及语言包路径是否在 CLI 下可读。其它所有“联动配置”,都是把两个正交系统强行拧在一起,反而增加维护成本。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











