CLI下Lang::get()返回原码或空字符串是因为语言环境未初始化,必须手动调用Lang::setLang()和Lang::load(),且路径、键名、大小写须严格匹配,多应用时需注意语言包路径。

CLI 模式下 Lang::get() 返回原码或空字符串,不是语言包没加载,而是语言环境根本没初始化——Lang::setLang() 没调、Lang::load() 被跳过、或语言包路径写错。
CLI 下语言环境必须手动激活
Web 请求中语言可能由中间件自动设好,但 CLI 启动时 Lang 状态是初始值(默认 en-us),不调 Lang::setLang('zh-cn') 就永远取不到中文。这不是“自动 fallback”,是压根没切换。
- 必须在命令类的
handle()开头显式设置:Lang::setLang('zh-cn'); - 紧接着要主动加载对应语言文件:
Lang::load(app()->getAppPath() . 'lang/zh-cn/validate.php');(验证器提示)或Lang::load(app()->getAppPath() . 'lang/zh-cn/message.php');(通用消息) - 别依赖
Lang::detect()—— CLI 没$_SERVER['HTTP_ACCEPT_LANGUAGE'],它直接返回en-us
语言包路径和键名必须严格匹配
路径错一个字母、文件名大小写不对、键名拼写偏差,Lang::get('user_not_found') 都会静默返回 'user_not_found',不会报错也不会警告。
- 确认语言包真实存在:
app/lang/zh-cn/validate.php(不是zh_CN或zh-cn.php) - 验证器错误键名必须带字段前缀,例如:
'user_email.email' => '邮箱格式不正确',不能只写'email' => '...' - 自定义错误码如
'10001'或'order_expired',必须在所有语言包里保持完全一致(包括单引号、大小写、下划线)
多应用模式下语言包位置容易错
如果启用了多应用(如 app/api/),CLI 命令默认加载的是主应用的语言包路径,子应用的 lang/ 目录不会自动纳入搜索范围。
立即学习“PHP免费学习笔记(深入)”;
- 不要假设
app()->getAppPath()会指向子应用目录;CLI 执行命令时当前应用仍是默认的index - 若命令属于
api应用,需手动拼路径:Lang::load(app()->getAppPath() . '../api/lang/zh-cn/validate.php'); - 更稳妥的做法:把共用语言包统一放在
app/lang/下,子应用配置不单独放语言目录
最常被忽略的是:CLI 下 Lang::get() 的行为和 Web 完全一致,但它不继承任何请求上下文,一切都要从零开始 setup——漏掉 setLang() 或 load() 任意一步,就等于没开灯却指望看得见。



















