关键在于语言标识作为URI第一段需被路由、控制器、语言加载协同识别:路由用$route['(en|zh)(/:any)'] = '$2'透传路径,MY_Controller中取segment(1)设语言并重载文件,.htaccess规则须含[L]且排除静态资源,语言文件名必须含_lang.php、load()第二参数须匹配目录名,任一环节标识不一致即中断。
CodeIgniter 实现
多语言
URL(如
、
)的关键不在「加个参数」,而在于让语言标识成为 URI 第一段,并被
路由
、控制器、语言加载三者协同识别——否则会出现 404、语言不切换、URL 回退带多余段等典型问题。
怎么配置路由让
正确匹配控制器
不能只靠
这类静态规则,必须捕获语言段并透传后续路径:
—— 匹配带子路径的情况,如
—— 单独访问语言根路径时指向首页
这两条必须放在
靠前位置,且在
之后、其他泛匹配规则之前,否则会被
提前吞掉
注意:正则括号里不要加空格,
有效,
会导致匹配失败
为什么继承
比用 Hook 更可控
用
或
Hook 加载语言,容易在重定向、AJAX 请求或 CLI 调用中出错;而控制器基类能确保每次 HTTP 请求都走同一套逻辑:
在
中用
取第一段,判断是否为合法语言码(需提前定义
)
调用
后,必须紧接着
,否则视图中
仍读默认语言文件
别忘了设置
,否则生成的
或
不会自动补上前缀
如果控制器没继承
(比如直接继承
),语言切换就完全失效——这点极易被忽略
里 RewriteRule 的顺序和标志直接影响多语言 URL 是否生效
Apache 重写规则不是“写了就通”,顺序和标志错一个,
就可能变成
或直接 404:
灵活路由的PHP库
灵活路由的PHP库
下载
必须启用
,且确保 Apache 已加载
关键规则要写成:
—— 注意末尾的
表示“最后一条”,防止后续规则干扰
和
必须存在,否则静态资源(如
)也会被转发到 PHP,导致 500 错误
若项目部署在子目录(如
),
中的路径要补上子目录名:
语言文件加载和
调用的常见断裂点
即使 URL 和路由都对了,
还是显示英文,大概率卡在这几个环节:
语言文件路径必须严格为
,其中
—— 文件名必须含
,变量名必须是
的第二个参数是语言目录名,不是语言码;如果目录叫
,这里就得传
,而非
视图中用
前,控制器必须已执行过
;不能依赖 config 中的默认语言设置来“兜底”
缓存问题:CI 默认缓存语言文件,改完
后要清
下相关文件,否则看不到更新
真正难的不是写几行路由或加个
,而是所有环节——从 Apache 重写、CI 路由解析、控制器语言感知、到视图函数调用——必须用同一套语言标识逻辑串起来。任意一环把
当字符串处理、另一环当目录名处理,就会断在中间。
/en/about/zh/contact/en/xxx$route['(en|zh)'] = 'home';$route['(en|zh)(/:any)'] = '$2';/en/blog/post/123$route['(en|zh)'] = 'home';routes.php$route['default_controller']$route['(:any)'](en|zh)(en | zh)MY_Controllerpre_controllerpost_controller_constructorMY_Controller::__construct()$this->uri->segment(1)$allowed_langs = ['en', 'zh', 'ja']$this->config->set_item('language', $lang)$this->lang->load()lang()$this->config->set_item('lang_path', "$lang/");base_url()site_url()MY_ControllerCI_Controller.htaccess/en/aboutindex.php?/en/aboutRewriteEngine Onmod_rewriteRewriteRule ^(.+)$ index.php?/$1 [L][L]RewriteCond %{REQUEST_FILENAME} !-f!-d/en/assets/css/app.csshttp://example.com/myapp/RewriteRuleRewriteRule ^(.+)$ /myapp/index.php?/$1 [L]lang()lang('welcome')application/language/en/welcome_lang.php$lang['welcome'] = 'Hello';_lang$lang$this->lang->load('welcome', 'en')english'english''en'lang('welcome')load()welcome_lang.phpapplication/cache/_lang.phpen