codeigniter 实现真多语言需统一前置路由拦截与语言识别:在 routes.php 用正则匹配语言前缀并重写 uri,在 my_controller 构造函数中提取 segment(1) 设置语言,结合 session、hreflang、canonical 及 lang_url() 辅助函数确保 seo 正确。

CodeIgniter 默认不支持带语言前缀的 SEO 友好 URL(比如 /en/about 或 /zh/news),直接改 $config['language'] 只能全局切换,无法让不同 URL 对应不同语言版本——这会导致搜索引擎抓取混乱、canonical 错乱、hreflang 缺失,实际就是伪多语言。
如何让 URI 第一段识别为语言代码并路由到对应控制器
不能依赖 _remap() 在每个控制器里手动解析第一段,那样重复、易错、且无法统一处理 404 或重定向逻辑。正确做法是统一前置拦截:
- 在
application/config/routes.php中,用正则预定义语言前缀路由,例如:$route['^(en|zh|ja|ko)/(.+)$'] = '$2';<br>$route['^(en|zh|ja|ko)$'] = 'home/index';<br>$route['default_controller'] = 'home/index';
- 再在
application/core/MY_Controller.php的构造函数中提取并设置语言:$this->lang_code = $this->uri->segment(1);<br>if (in_array($this->lang_code, ['en', 'zh', 'ja', 'ko'])) {<br> $this->session->set_userdata('language', $this->lang_code);<br>} else {<br> $this->lang_code = $this->session->userdata('language') ?: 'en';<br>} - 注意:必须在
parent::__construct()之后读$this->uri,否则segment(1)为空
为什么不能只靠 session 或 cookie 切换语言而不改 URL
搜索引擎不会执行 JS 点击切换语言,也不会携带你的 session;纯靠 cookie 切换后,/about 这个 URL 对所有语言都一样,Google 无法区分 /about 是英文页还是中文页,必然导致收录错乱、排名下降。
- hreflang 标签必须配合真实 URL 生效,例如:
<link rel="alternate" hreflang="zh" href="https://example.com/zh/about"> - canonical 应指向当前语言的绝对 URL,不能写成
/about - 用户分享链接时,语言状态必须固化在 URL 中,否则别人点开就回退到默认语言
加载语言文件时怎么避免硬编码语言目录名
CodeIgniter 的 $this->lang->load() 第二个参数必须是语言目录名(如 'zh'),但这个值要和 URI 段或 session 保持一致,不能写死。
- 不要在每个控制器里重复写:
$this->lang->load('menu', 'zh'); - 应在
MY_Controller构造函数中统一加载:$lang = $this->session->userdata('language') ?: 'en';<br>$this->lang->load('menu', $lang);<br>$this->lang->load('common', $lang); - 语言文件名(如
menu_lang.php)必须放在对应子目录下:application/language/zh/menu_lang.php,否则加载失败且无报错提示 - 若用数据库存翻译,仍需通过
$this->lang->load()注入数组,不能跳过语言类直接 echo 数据库字段
生成多语言链接时容易漏掉的关键点
很多人用 base_url('about') 或 site_url('about') 生成链接,结果所有语言都指向同一路径,hreflang 失效。
- 必须封装一个辅助函数,例如:
function lang_url($uri = '', $lang = NULL) {<br> $ci =& get_instance();<br> $lang = $lang ?: $ci->session->userdata('language') ?: 'en';<br> return site_url($lang . '/' . ltrim($uri, '/'));<br>} - 模板中调用:
@#@#@#@#@#@#@#@#@#@0 - 注意:
$uri参数不能带开头斜杠,否则拼出/zh//about;也不能漏传hreflang属性,这是 Google 识别多语言页面的核心信号
最常被忽略的是:语言切换链接本身也得带完整路径上下文。比如用户在 /zh/product/123 页面点“English”,目标应该是 /en/product/123,而不是 /en —— 否则体验断裂,SEO 权重也无法继承。











