webman唯一原生支持的翻译函数是trans(),必须配置config/translation.php包含locale、fallback_locale和path三项,且path须为绝对路径,语言文件需置于lang/{locale}/messages.php中并严格匹配命名与格式。

Webman 里没有开箱即用的 i18n() 函数,直接调用会报 Call to undefined function i18n();它默认只认 trans(),且必须配好 config/translation.php —— 这是绝大多数人踩坑的第一步。
trans() 是 Webman 唯一原生支持的翻译函数
Webman 的国际化基于 symfony/translation,不是 Laravel 风格的 __(),也不是自定义的 i18n()。你写的 i18n('hello') 永远不会执行,除非你自己注册了该函数(需 Composer 自动加载 + 手动定义)。
正确做法是:
-
config/translation.php必须存在,且返回数组,含locale、fallback_locale、path三项 -
path必须是绝对路径,例如:__DIR__ . '/../lang',不能写./lang或lang - 语言文件放在
lang/{locale}/messages.php,例如lang/zh_CN/messages.php - 每个
messages.php必须以return [...]开头,不能有输出、BOM、空行或注释
示例 lang/zh_CN/messages.php:
return [
'welcome' => '欢迎',
'login' => '登录',
];
控制器中调用:trans('welcome') → 返回 "欢迎";trans('welcome', [], 'en_US') → 强制用英文包。
language 文件夹结构和命名必须严格匹配 locale
Webman 不做容错解析:如果请求 locale=en_US,但 lang/en_US/messages.php 不存在,或写成了 en-us/messages.php 或 en_US.php(没套 messages.php),trans() 就静默回退到 fallback_locale,甚至直接返回键名本身。
关键约束:
Gene6 FTP Server Professional v3.10.0.2 多语言特别版(集成了中文)
- 子目录名(如
en_US)必须和config/translation.php中的locale值完全一致(大小写、下划线都不能错) - 每个 locale 目录下必须是
messages.php,不支持auth.php等多文件拆分(除非你手动配置symfony/translation的 loader) - 不支持嵌套数组键,例如
'auth.login' => '登录'会被当作文本键处理,trans('auth.login')查不到 —— 必须写成'auth_login' => '登录'
切换语言必须重设 trans() 上下文,不能只改 Session 或 Cookie
很多人设了 $_SESSION['locale'] = 'ja_JP' 就以为页面会自动切语言,结果刷新后还是中文 —— 因为 trans() 在单次请求中缓存了 translator 实例,它不监听 Session 变更。
正确做法是在中间件或控制器基类的初始化逻辑里做三件事:
- 从 URL 参数(
?lang=ja_JP)、Cookie 或 Session 中读出目标 locale - 校验该 locale 是否在
config/translation.php的available_locales白名单里(需自己加逻辑判断) - 调用
app('translator')->setLocale($locale)(注意不是setlocale()系统函数) - 确保这个操作发生在任何
trans()调用之前,比如放在中间件handle()开头
否则,即使 locale 切换了,trans() 仍用的是请求开始时加载的旧实例。
想用 i18n() 函数?得自己注册,且注意加载时机
如果你坚持要用 i18n('hello'),可以自己定义一个函数并让 Composer 自动加载,但要注意两点:
- 函数体内部必须调用
app('translator')->get('messages')->trans(...),不能绕过 translator 实例 - 该函数文件(如
app/Helper/i18n.php)必须在composer.json的"autoload": {"files": [...]}中声明,否则不会被加载 - 不能在
config/i18n.php里定义函数 —— Webman 不自动加载这个文件,它只是个普通 PHP 文件
更稳妥的做法是:放弃 i18n(),统一用 trans(),避免混淆和隐式依赖。
最易被忽略的一点:Webman 不像 Laravel 有 App::setLocale() 全局钩子,它的 translator 实例是容器绑定的单例,但 locale 设置是 per-request 的 —— 每次请求都得显式 set,漏一次,整页就回退到默认语言。










