ThinkPHP6无内置“多语言授权提示”,需在权限校验失败时调用lang()获取翻译文案,并确保语言包已加载、键名一致、中间件中提前设置语言环境。

ThinkPHP6 本身不提供“多语言授权提示”这个内置功能,它也没有所谓“授权提示”的概念。你实际需要的,是在用户无权限访问某资源时,用当前语言显示友好的拒绝提示
这类提示属于业务逻辑中的权限拦截环节,需结合多语言机制手动实现——关键不是“添加授权提示”,而是确保权限校验失败后调用 lang() 或 Lang::get() 获取对应语言的文案,且该文案必须存在于当前激活的语言包中。
确保语言环境已就绪
权限校验(如中间件、行为、控制器前置逻辑)发生得非常早,若此时语言未设置或语言包未加载,lang('no_permission') 就会直接返回 'no_permission' 字符串,而非翻译内容。
- 推荐在全局中间件(如 LoadLangPack 或自定义 LangInit 中间件)中完成 Lang::setLang() 和 Lang::load(),且必须在任何权限判断之前执行
- 避免在控制器构造函数中设语言——此时中间件尚未运行,Lang 状态仍是初始值
- 若用 Cookie 或 Session 存储用户语言偏好,应在中间件里读取并立即设置:
$lang = $request->cookie('think_lang', config('lang.default_lang'));→Lang::setLang($lang);
在权限拦截处使用语言键名
不要硬编码提示文字,所有拒绝文案都应走语言包。例如:
立即学习“PHP免费学习笔记(深入)”;
- 在权限中间件中:
return json(['code' => 403, 'msg' => lang('access_denied')]); - 在控制器方法开头:
if (!$this->auth->check('user/edit')) { $this->error(lang('no_permission')); } - 在验证器或模型中触发权限检查失败时,也应统一调用 lang() 而非写死字符串
语言包中正确定义授权相关键名
在 app/lang/zh-cn.php 和 app/lang/en-us.php 中,分别定义一致的键名:
-
app/lang/zh-cn.php:'access_denied' => '访问被拒绝', 'no_permission' => '您没有操作权限' -
app/lang/en-us.php:'access_denied' => 'Access Denied', 'no_permission' => 'You do not have permission to perform this action' - 键名必须完全一致(大小写、拼写、下划线/短横线),否则 lang('xxx') 在非默认语言下将静默回退为原字符串
- 不建议把授权提示写进 validate.php —— 它专用于验证规则,应放在 common.php 或独立的 auth.php 中
插件或模块内需独立处理
如果你的权限控制逻辑位于插件(如 app/plugin/Pay/)中,主应用的语言设置不会自动生效:
- 插件需自建
lang/zh-cn/common.php和lang/en-us/common.php - 注册专属中间件(如
plugin\Pay\middleware\AuthLangSwitch),在 handle() 开头读取插件专用 Cookie(如plugin_pay_lang)并调用Lang::set($lang) - 确保该中间件在插件路由前执行,早于任何权限判断



















