CI3路由写在application/config/routes.php用数组赋值,CI4则在app/Config/Routes.php中调用$routes->get()等方法;占位符需精确选用,避免:any误匹配;REST路由优先用resource();匹配顺序从上到下,泛化规则须置尾;CI4改路由后须清缓存。

路由规则写在哪儿?别搞错版本路径
CodeIgniter 3 和 4 的路由文件位置、语法完全不同,混用直接 404。不是“改对了没效果”,而是根本没加载你的规则。
- CI3:所有规则写在
application/config/routes.php,用$route['uri'] = 'controller/method';这种数组赋值形式 - CI4:路由配置在
app/Config/Routes.php,必须调用$routes->get()、$routes->post()等方法,直接写数组会报错 - CI4 中
$route数组已废弃,若旧项目升级后还留着 routes.php 里的$route定义,它们会被完全忽略
占位符怎么选?:num 和 :any 不是万能钥匙
:num 只匹配纯数字(如 123),:any 匹配除 / 外的任意字符——但这也意味着它可能吞掉你本想留给下一个 segment 的内容,导致路由冲突或参数错位。
- 用户访问
/article/php-tips-2026,用$route['article/(:any)'] = 'blog/show/$1';是可行的;但若后面加一条$route['article/archive/(:num)'] = 'blog/archive/$1';,前者会先匹配成功,后者永远不触发 - CI4 推荐用更精确的
:segment(等价于 CI3 的:any)或自定义占位符,比如$routes->addPlaceholder('slug', '[a-z0-9\-]+');,再写$routes->get('post/(:slug)', 'Post::view');,既安全又语义清晰 -
:any在 CI3 中无法匹配含英文句点(.)的 URI,比如/file/report.pdf会失败;此时得用正则:$route['file/([a-zA-Z0-9\-\_\.]+)'] = 'files/download/$1';
RESTful API 路由别硬凑,用资源路由省错漏
手写一堆 api/users/(:num) + 方法限定,容易漏掉 PUT/DELETE、错配 HTTP 动词、或忘记加权限校验入口。CI4 的 $routes->resource() 是专为此设计的快捷方式。
- 写
$routes->resource('users');,自动注册 7 条标准 REST 路由(GET /users、POST /users、GET /users/(:id)等),控制器只需实现对应方法名(index、create、show) - CI3 没原生资源路由,硬写易出错;可用
$route['api/users']['get'] = 'api/users/index';这类带方法限定的写法,但必须每条都手动补全,且不能依赖框架自动识别动词 - 资源路由默认不包含
POST /users/new这类表单页路由(那是 Web 场景),API 场景下应关闭:$routes->resource('users', ['except' => ['new', 'edit']]);
为什么路由生效了却跳转错控制器?检查顺序和覆盖逻辑
路由匹配是「从上到下」逐条比对,一旦命中就停止,后面的规则形同虚设。这不是 bug,是设计机制——但很多人以为“越靠后越优先”。
- 错误写法:
$route['(:any)'] = 'pages/view/$1';放在最前面,它会吃掉所有请求,包括/admin、/api/login,导致后台和 API 全挂 - 正确顺序:先写具体规则(如
$route['login'] = 'auth/login';),再写泛化规则(如$route['(:any)'] = 'pages/view/$1';),且泛化规则务必放在最后 - CI4 中
$routes->set404override()必须显式调用,否则即使写了$routes->set404override('Errors::show404');,404 仍走默认页;CI3 则是直接赋值$route['404_override'] = 'errors/page_missing';
最常被跳过的其实是缓存——CI4 默认开启路由缓存,改完 Routes.php 不清缓存,新规则永远不生效;执行 php spark cache:clear 或删掉 writable/cache/route/ 目录即可。这点连不少老手都会卡住两小时。










