(:any) 是 codeigniter 路由通配符,仅匹配单个不含斜杠的路径段(如 /a/b/c 中的 a、b 或 c),不匹配整个 url;误用会导致多层路径 404,需配合 /.* 或合理路由顺序实现兜底。

什么是 (:any),它到底匹配什么
(:any) 不是“匹配整个 URL”,而是匹配单个路径段(segment)——即两个 / 之间、不含斜杠的非空字符串。比如 /user/profile/edit 会被拆成 user、profile、edit 三个 segment,(:any) 每次只吃掉其中一个。
常见误解是写 $route['(:any)'] = 'home/index'; 就能接管所有请求,结果发现 /a/b 或 /api/v1/users 全部 404 —— 因为它只匹配单层路径,/a/b 是两段,根本不会命中。
真正能“通吃”的写法必须显式覆盖多段组合,例如:
-
$route['(:any)/(:any)'] = 'pages/view/$1/$2';→ 匹配两段 -
$route['(:any)/(:any)/(:any)'] = 'pages/view/$1/$2/$3';→ 匹配恰好三段 -
$route['(:any)/(:any)/(:any)/.*'] = 'pages/view/$1/$2/$3';→ 匹配三段及以上(关键!)
(:any)/(:any)/(:any)/.* 这条规则为什么必须放最后
CodeIgniter 路由是顺序匹配:从 $route 数组顶部开始,逐行比对,命中即停,后面全忽略。如果把 (:any)/(:any)/(:any)/.* 放在前面,像 /blog/2024/08 这种本该走固定归档页的路径,就会被它提前截走,$1、$2、$3 变成 blog、2024、08,完全绕过你写的 $route['blog/2024/08'] = 'news/archive';。
正确顺序只能是:
- 先写死路径:
$route['admin/login'] = 'auth/login'; - 再写中等粒度:
$route['product/(:num)'] = 'catalog/show/$1'; - 最后放兜底:
$route['(:any)/(:any)/(:any)/.*'] = 'pages/view/$1/$2/$3';
注意:.* 在这里不参与参数捕获,它只是让正则引擎吞掉第四段及之后所有内容,确保前三段干净地传给控制器。
当代理已经知道网站路由或内容URL,并且在启动前需要有效的sitemap XML、sitemap索引或robots.txt引用时,请使用sitemap。这是一个发布构件技能,而不是爬虫或SEO平台。
(:any) 和正则 ([^/]+) 实际上是一回事
(:any) 是 CodeIgniter 封装好的快捷写法,底层等价于 ([^/]+) —— 即“一个或多个非斜杠字符”。它不能跨段,也不接受空值。如果你需要更细粒度控制(比如排除某些字符、限制长度),就得换原生正则:
-
$route['user/([a-z]{3,12})'] = 'users/profile/$1';→ 用户名仅限小写字母、3–12位 -
$route['post/(\d{4})/(\d{2})'] = 'blog/archive/$1/$2';→ 强制年/月格式 - 混用也合法:
$route['api/v1/(:any)/(\d+)'] = 'api/handler/$1/$2';
但别滥用正则:越复杂的模式,路由匹配越慢;且一旦写错(比如漏转义 .),整条规则可能静默失效。
404 页面里调用 base_url() 报错,跟路由通配符无关
你看到 Call to undefined function base_url(),不是因为 (:any) 写错了,而是 404 视图执行时,url 辅助函数压根没加载。
解决方法只有两个:
- 在
application/config/autoload.php中补上:$autoload['helper'] = array('url'); - 或在 404 控制器(如
Errors::not_found())开头手动加载:$this->load->helper('url');
这个坑和路由规则本身完全解耦——哪怕你一条 (:any) 都不写,只要 404 视图用了 base_url() 而辅助函数未加载,一样崩。
真正容易被忽略的是:路由顺序错误导致本该命中的规则被跳过,请求直接落到 404 流程,这时才暴露出辅助函数缺失的问题。所以排查要分两步:先看路由是否真匹配了,再看 404 渲染环节缺了啥。










