ci3与ci4路由完全不兼容:ci3用application/config/routes.php中$route数组赋值,ci4用app/config/routes.php中$routes->get()等方法注册;升级必须删除所有$route[]写法,改用controller::method语法,并清缓存。

CI 路由规则写错,90% 是因为版本混淆或占位符滥用 —— 不是语法不会,而是没看清 CI3 和 CI4 的根本差异。
CI3 和 CI4 的路由文件位置与语法完全不兼容
CI3 的路由写在 application/config/routes.php,靠赋值 $route['xxx'] = 'controller/method';;CI4 则必须写在 app/Config/Routes.php,用 $routes->get()、$routes->post() 等方法注册。两者混用,规则根本不会加载,页面直接 404,连报错都看不到。
升级项目时尤其要注意:$route 数组在 CI4 中已彻底废弃。哪怕你把旧规则原样复制进 CI4 的 routes.php,它也会被忽略。
- CI3 升级到 CI4 后,必须删掉所有
$route[...]写法,改用$routes->get('uri', 'Controller::method'); - CI4 中控制器方法名默认是静态调用(
Controller::method),不是controller/method字符串 - CI4 修改路由后必须清缓存:
php spark cache:clear,否则新规则不生效
正则路由怎么写才安全:别乱用 (:any)
(:any) 在 CI3 中匹配除 / 外的任意字符,但它不匹配英文句点(.),比如 /file/report.pdf 就会失败;CI4 中虽支持 :segment(等价于 :any),但依然建议避免泛化匹配。
真正需要正则时,直接写原生正则更可控:
当代理已经知道网站路由或内容URL,并且在启动前需要有效的sitemap XML、sitemap索引或robots.txt引用时,请使用sitemap。这是一个发布构件技能,而不是爬虫或SEO平台。
- CI3:
$route['article/([a-z0-9\-]+)'] = 'blog/show/$1';—— 明确只接受小写字母、数字和短横线 - CI4:
$routes->get('post/([a-z0-9\-]+)', 'Post::view');—— 不依赖占位符,语义清晰 - 想让 slug 支持大小写?CI3 可用
$route['([a-zA-Z0-9]+)'] = 'pages/view/$1';;CI4 推荐先注册自定义占位符:$routes->addPlaceholder('slug', '[a-zA-Z0-9\-]+');,再写$routes->get('page/(:slug)', 'Page::view');
REST 路由别手写,用 resource() 防漏配
手写 $route['api/users/(:num)']['get'] = 'api/users/show'; 这类规则,容易漏掉 PUT/DELETE、错配动词、或忘记加权限入口。CI4 的 $routes->resource('users') 会自动注册全部 7 条标准 REST 路由(GET /users、POST /users、GET /users/(:id) 等)。
- API 场景下务必排除表单页路由:
$routes->resource('users', ['except' => ['new', 'edit']]); - CI3 没原生
resource(),硬写易出错;可用带动词限定的数组写法,但必须每条都手动补全,且无法自动识别 HTTP 方法 - 资源路由的控制器方法名是约定死的(
index、show、create等),不能随意改名
路由顺序和优先级比语法更重要
CI 的路由匹配是从上到下逐条执行的,一旦命中就停止。所以泛化规则(如 $route['(:any)'] = 'pages/view';)必须放在最后,否则会吞掉所有后续规则。
CI4 同理:$routes->get('(:any)', 'Fallback::handle'); 这种兜底路由,必须写在所有明确路由之后。
- 调试时可临时在
routes.php里加var_dump($route);(CI3)或print_r($routes->getRoutes());(CI4)确认实际加载顺序 - CI4 中如果用了
$routes->redirect(),它也参与匹配顺序,不是“后处理” - 带参数的路由(如
user/(:num))优先级高于无参路由(如user/profile),但前提是它们不冲突 —— 实际开发中建议用更具体的路径前缀区分
最常被忽略的一点:CI3 的正则路由里,$1、$2 引用的是括号捕获组,而 CI4 的 $1 在字符串式回调里才有效;现代写法推荐用命名参数或直接传参,避免位置错位。










