codeigniter 4 不自动支持 locale 前缀路由,必须手动配置路由捕获、过滤器标准化和控制器动态加载语言包三者协同;缺一即导致404、重定向循环或翻译失效。

CodeIgniter 4 本身不自动支持带 locale 前缀的多语言路由(如 /zh-CN/about 或 /en/contact),必须手动配置三件事:路由规则捕获语言段、过滤器识别并标准化 locale、控制器中动态加载对应语言包。缺一不可,否则容易出现 404、重定向循环或翻译不生效。
1. 在路由中显式声明语言段
不能依赖“通配符自动匹配”,需用正则明确提取第一段作为 locale,并按优先级排序:
- 在
app/Config/Routes.php中,把带 locale 的路由写在最前面,避免被通用路由吞掉 - 使用正则约束语言段,例如只允许
en|zh-CN|ja-JP|fr-FR等已支持的值 - 示例:
$routes->get('(:any)/(:segment)/(:segment)', 'Home::view/$2/$3', ['filter' => 'locale', 'constraints' => ['any' => 'en|zh-CN|ja-JP|fr-FR']]);
?>
注意:不要用 $routes->addPlaceholder() 简单替换,它无法做合法性校验;也别把 locale 路由放在 $routes->set404Override() 后面,否则会失效。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
2. 用过滤器统一处理 locale 提取与跳转
创建一个 LanguageControl 过滤器(app/Filters/LanguageControl.php),核心是:只在 URL 没有合法语言段时才重定向,且重定向目标 URL 必须确保语言段存在且位置正确。
- 用
$uri->getSegments()获取段数组,检查$segments[0]是否为支持的 locale(注意大小写敏感) - 若不合法或为空,构造新 URL:拼接
base_url()+ 默认 locale + 原路径,然后return redirect()->to($newUrl) - 切忌用
array_unshift()修改段数组再拼接——这极易导致索引错位和无限重定向 - 务必在重定向前加判断:如果当前请求已是带合法 locale 的 URL,直接放行,不执行任何跳转
3. 控制器中激活对应语言环境
即使 URL 和路由都对了,语言包也不会自动加载。每个需要多语言的控制器方法里,必须手动设置:
- 从 URI 获取语言段(如
$locale = $this->request->getUri()->getSegment(1) ?? config('App')->defaultLocale;) - 用
$this->config->locale = $locale;设置当前 locale - 调用
$language->load('message', $locale)加载指定分组(第二个参数必须与app/Language/下目录名完全一致) - 如果切换 locale 后翻译没变,记得清空语言缓存:
cache()->delete('language_'.$locale);
4. 补充:数据库多语言内容怎么关联
CI4 的 Language 类只管 PHP 数组里的字符串,不管数据库字段。如果你有标题、描述等需要多语言的内容,得自己设计结构:
- 建一张
pages_i18n表,含page_id、locale、title、content字段 - 查询时用
where(['page_id' => $id, 'locale' => $this->config->locale])关联获取 - 前端链接生成也要带当前 locale,比如
site_url($locale.'/about'),别硬写死/en/about










