CodeIgniter多语言核心是让语言标识为URI第一段并同步路由、控制器与语言加载:路由用正则剥离前缀透传路径,MY_Controller中先parent再取segment(1)设语言并重载文件,语言目录名、load()参数、URI段、session值四者必须严格一致。

CodeIgniter 实现多语言支持,核心不是改 $config['language'] 那一行,而是让语言标识成为 URI 第一段(如 /zh/about),并确保路由、控制器、语言加载三者同步识别——任一环节断开,就会出现 404、$this->lang->line() 返回空、URL 回退带多余段等实际问题。
路由必须剥离语言段,否则控制器收不到真实路径
CodeIgniter 默认把 /zh/about 中的 zh 当作控制器名处理。不剥离,$this->uri->segment(2) 就是 about,但 $this->router->class 已变成 zh,直接 404。
-
$route['^(en|zh|ja|ko)/(.+)$'] = '$2';—— 匹配带子路径的情况,透传真实控制器/方法 -
$route['^(en|zh|ja|ko)$'] = 'home/index';—— 单独访问语言根路径时指向首页 - 这两条必须放在
routes.php靠前位置,且在$route['default_controller']之后、泛匹配规则(如$route['(:any)'])之前,否则被提前吞掉 - 正则括号里不能有空格:
(en|zh)有效,(en | zh)失效
MY_Controller 中取 segment(1) 设语言,顺序和时机不能错
$this->uri->segment(1) 在 parent::__construct() 之前是空的,因为 URI 对象还没初始化;用 Hook 加载语言则容易在 CLI、AJAX 或重定向中漏掉。
- 在
MY_Controller::__construct()中,先调parent::__construct(),再读$this->uri->segment(1) - 校验是否为合法语言码:
if (in_array($lang, ['en', 'zh', 'ja'])) { ... },避免把非法段当语言 - 设语言后必须立刻重载:
$this->config->set_item('language', $lang); $this->lang->load('common', $lang);,否则lang()仍用旧缓存 - 别忘了
$this->config->set_item('lang_path', "$lang/");,否则site_url()不自动补前缀 - 如果某个控制器没继承
MY_Controller(比如直继承CI_Controller),语言切换就完全失效
语言文件路径、命名、加载参数必须严格一致
放错目录、写错后缀、传错参数,$this->lang->line() 都静默返回空,不报错也不提示。
- 语言文件必须放在
application/language/zh/(不是zh_cn或zh-CN),子目录名全小写、下划线分隔仅用于带地区码场景(如zh_cn),纯语言码用zh - 文件名必须以
_lang.php结尾,如common_lang.php;$this->lang->load('common', 'zh')中第一个参数不含_lang,第二个参数必须与子目录名完全一致 -
$lang['user_login'] = '登录';键名不能含空格或特殊字符,否则后续调用失败 - 切换语言时要清缓存:
$this->lang->is_loaded = array();,再load()新语言,否则旧内容还在
SEO 和链接生成必须绑定当前语言上下文
只靠 session 或 cookie 切换语言,URL 不变,搜索引擎无法区分 /about 是英文页还是中文页,canonical 和 hreflang 全部失效。
- 所有内部链接必须用
lang_url()这类自定义辅助函数生成,例如lang_url('about')输出/zh/about,而非硬写site_url('about') -
<link rel="alternate" hreflang="zh" href="https://example.com/zh/about">必须根据当前语言动态输出 -
<link rel="canonical" href="https://example.com/zh/about">同样要带语言前缀,不能写成/about - 用户分享链接时,语言状态必须固化在 URL 中,否则别人点开就回退到默认语言
最易被忽略的是:语言目录名、load() 的第二个参数、URI 第一段、session 存储值这四者必须完全一致;差一个字母或大小写,整个链条就断了。调试时优先检查 $this->uri->segment(1) 值、$this->config->item('language') 值、application/language/ 下是否存在对应子目录这三个点。


















