codeigniter重定向路由($route['old']='new')是服务端内部映射,不发http响应,适用于隐藏真实路径、统一入口和权限预检;需用header()或ci4 redirect()实现真正的301/302跳转。

重定向路由适合处理 URL 变更和访问控制
CodeIgniter 的重定向路由($route['old'] = 'new';)本质是服务端内部跳转,不是 HTTP 301/302 响应,它适用于需要“悄悄换路”而不暴露真实路径的场景。比如后台模块重构后控制器改名,但旧链接还在邮件或书签里;又或者想把 /blog/123 统一映射到 Posts::view,避免在每个控制器里重复解析 ID。
- 旧 URL 结构迁移(如从
/article/(:num)改为/post/(:num)) - 统一入口路由(把多个相似路径收归一个控制器方法处理)
- 隐藏真实控制器名(对外暴露
/dashboard,实际调用AdminHome::index) - 配合过滤器做权限预检(路由匹配后、控制器执行前触发
filter)
不适用于 SEO 永久跳转或外部链接更新
如果你希望搜索引擎把旧 URL 的权重转移到新 URL,或者用户点击收藏夹里的链接时浏览器地址栏要变,那就不能只靠 $route 映射——它不会发 301 响应,爬虫和浏览器都感知不到“跳转”。这时候得用真正的 HTTP 重定向,比如:
- Nginx 的
return 301 /new-url;或rewrite - PHP 中手动
header('Location: /new-url'); exit; - CI4 的
redirect()函数(返回 302,默认不缓存)
注意:CI4 的 redirect()->route('named_route') 是发 HTTP 响应,而 $route['a'] = 'b' 是纯内部映射,两者层级不同,别混用。
命名路由 + 参数传递必须搭配动态路由规则
想用 redirect('editTest')->with($id) 这种写法?不行。CI4 原生 redirect() 不接受参数数组。真正能传参的方式只有一种:路由定义里预留占位符,并在调用时填值。
当代理已经知道网站路由或内容URL,并且在启动前需要有效的sitemap XML、sitemap索引或robots.txt引用时,请使用sitemap。这是一个发布构件技能,而不是爬虫或SEO平台。
- 先在
routes.php里写:$routes->get('edit/(:num)', 'Test_Controller::editTest/$1', ['as' => 'editTest']); - 再在控制器里调用:
return redirect()->route('editTest', [$passingID]); - 如果漏掉
$routes->get(...)中的/(:num)和$1,route('editTest', [...])就会生成错误 URL,比如/editTest/123而不是/edit/123
这个细节最容易被忽略:命名路由的参数填充能力完全依赖于路由定义中的捕获组,不是函数调用时临时拼的。
404 重定向和 _remap 是两种粒度不同的兜底策略
$route['404_override'] 是全局开关,一旦没匹配任何路由就触发;而 _remap() 是单个控制器内的拦截器,只管“本控制器里有没有这个方法”。它们解决的问题不同,但常被误当成替代方案。
- 用
$route['404_override'] = 'Errors::notFound';处理所有打错域名、输错路径的请求 - 用
_remap()在User_Controller里把/user/invalid-action自动转成/user/index,不走 404 流程 - 两者可以共存:_remap 先拦一遍,漏掉的再进 404_override
真正复杂的地方在于,_remap 里如果也调用了 redirect(),就变成一次内部映射 + 一次 HTTP 跳转,响应头、会话、性能都会受影响——这种嵌套重定向容易引发循环或丢失数据,上线前务必测清楚。










