codeigniter 多语言切换失败源于uri、路由、控制器、语言加载四环节未对齐:语言目录需全小写下划线命名且文件以_lang.php结尾;路由须提前剥离语言段;控制器需手动切换语言并加载对应语言包;ci4过滤器易引发重定向循环,关键在精准定位语言段。

CodeIgniter 多语言切换失败,往往不是配置写错那么简单,而是多个环节没对齐——URI、路由、控制器、语言加载四者必须严丝合缝,漏掉一个,$this->lang->line() 就静默返回空字符串,还不报错。
语言目录结构和文件命名不合规
CI 只认 application/language/ 下的子目录,且要求非常严格:
- 子目录名必须全小写 + 下划线分隔,比如
zh_cn,不能是zh-CN、ZH_CN或zhcn - 语言文件必须以
_lang.php结尾,例如common_lang.php,不能叫common.php或common_langs.php - 键名不能含空格或特殊字符:
$lang['user login'] = '登录';无效;得写成$lang['user_login'] = '登录'; - CI3 和 CI4 都不自动扫描子目录,文件必须放在正确路径下,否则
load()表面成功,实际没加载任何内容
路由未提前剥离语言段
URL 是 /zh_cn/login,默认会被当作控制器 zh_cn、方法 login,直接 404。必须在 routes.php 靠前位置加正则规则:
$route['^(zh_cn|en_us|ja_jp)/(.+)$'] = '$2';$route['^(zh_cn|en_us|ja_jp)$'] = 'home/index';- 这两条必须放在
$route['default_controller']之后、泛匹配规则(如$route['(:any)'])之前 - Apache 的
.htaccess要带[L]标志,否则重写可能被后续规则干扰
控制器中没手动切换语言配置
$config['language'] 在 config.php 里只设默认值,运行时不会随 URL 自动变。必须在 MY_Controller(CI3)或基类控制器(CI4)中处理:
- 先调
parent::__construct(),再读$this->uri->segment(1)(否则 segment 为空) - 判断是否为合法语言码,比如
in_array($lang, ['zh_cn', 'en_us']) - 执行
$this->config->set_item('language', $lang) - 紧接着
$this->lang->load('common', $lang),否则视图里lang('xxx')还是旧语言 - 若要立即生效,还得清缓存:
$this->lang->is_loaded = [];
CI4 中过滤器导致重定向循环
CI4 常用自定义过滤器(如 LanguageControl)处理语言段,但容易出问题:
- 错误识别语言段位置:比如
app.baseURL含子目录时,语言段可能在$segments[1]而非$segments[0] - 用
array_unshift()插入默认语言,会打乱路径段索引,导致下一次请求又被识别为“缺语言”,反复重定向 -
current_url()与$uri->getSegments()解析结果不一致,尤其在子目录部署场景下 - 解决关键是精准定位语言段位置,并避免修改原始 segments 数组,改用拼接方式构造新 URL











