codeigniter多语言支持需uri、路由、控制器、语言加载四者严格对齐:language目录下子目录须全小写加下划线(如zh_cn),文件名以_lang.php结尾,键名不含空格或特殊字符;路由须用正则剥离语言段(如$route['^(zh_cn|en_us)/(.+)$'] = '$2');my_controller中须先set_item('language', $lang)再load()并清缓存;restserver语言路径独立且键名不一致(如simplified-chinese),需显式加载。

CodeIgniter 多语言支持不是改个 $config['language'] 就完事——它必须让 URI、路由、控制器、语言加载四者对齐,否则 $this->lang->line() 一定返回空,而且不报错、不提示、不 fallback。
language 目录结构和文件命名必须严格匹配
CodeIgniter 只认 application/language/ 下的子目录,且子目录名必须全小写、下划线分隔(如 zh_cn),不能是 zh-CN 或 zhcn;语言文件必须以 _lang.php 结尾,比如 application/language/zh_cn/common_lang.php。键名不能含空格或特殊字符:$lang['user login'] = '登录'; 是无效的,得写成 $lang['user_login'] = '登录';。漏掉任一条件,$this->lang->load('common', 'zh_cn') 表面成功,但后续 $this->lang->line('user_login') 就静默返回空字符串。
路由必须提前剥离语言段,否则控制器收不到真实路径
如果 URL 是 /zh_cn/login,默认会被当成控制器 zh_cn、方法 login,直接 404。必须在 application/config/routes.php 靠前位置加规则:
$route['^(zh_cn|en_us|ja_jp|ko_kr)/(.+)$'] = '$2'; $route['^(zh_cn|en_us|ja_jp|ko_kr)$'] = 'home/index';
注意点:
- 正则括号内不能有空格,
(zh_cn | en_us)会失效 - 这两条必须放在
$route['default_controller']之后、泛匹配规则(如$route['(:any)'])之前 - Apache 的
.htaccess要带[L]标志,否则重写可能被后续规则干扰
MY_Controller 中必须手动 set_item + reload,不能只靠 config.php
$config['language'] 在 config.php 里设的是全局默认值,运行时不会自动随 URL 切换。要在 application/core/MY_Controller.php 构造函数中尽早处理:
- 先调
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 = [];
RestServer 的多语言错误消息依赖同一套机制,但路径不同
CodeIgniter RestServer 的语言文件不在 application/language/,而在 vendor/chriskacerguis/codeigniter-restserver/language/ 下,比如 simplified-chinese/rest_controller_lang.php。它用的是独立路径加载:$this->lang->load('rest_controller', $language, false, true, __DIR__.'/../');。这意味着:
- 你不能只靠
$this->config->set_item('language', 'zh_cn')让 RestController 自动切语言 - 必须在 REST 控制器里显式传入语言码,或从请求头(
Accept-Language)解析后手动 load - 简体中文键名是
simplified-chinese,不是zh_cn,目录名不一致会导致加载失败 - 部分翻译项(如
text_rest_ip_address_time_limit)在中文包里缺失,需自行补全,否则返回英文原串
最常被忽略的一点:语言切换后,site_url() 和 base_url() 不会自动加语言前缀——如果你要生成带 /zh_cn/ 的链接,得自己拼,或者重写辅助函数。URL 里的语言标识不是装饰,它是整个多语言链路的起点,断了哪一环,后面全空。











