Codeigniter 3 URI路由:如何编程获取URL对应的路由右侧规则
在CodeIgniter 3中获取任意URL对应的路由目标规则
好问题!CodeIgniter 3的官方路由类确实没有提供直接公开的方法来实现你要的功能——也就是根据给定的URL片段反向匹配路由规则并返回对应的目标路径。不过你提到的_parse_routes方法确实是核心所在,我们可以基于它的逻辑封装一个自定义函数。
核心思路
CI3的路由系统默认是处理** incoming 请求**,将URL映射到控制器方法,但没有内置的反向查询能力。不过Router类的受保护方法_parse_routes里已经包含了路由匹配的核心逻辑,我们可以复制并修改这部分逻辑,做成一个公开的自定义方法,接收指定URL并返回对应的路由目标。
自定义实现方案
最符合CI3架构的方式是扩展核心Router类,创建一个MY_Router子类:
- 在
application/core/目录下创建MY_Router.php文件,内容如下:
<?php defined('BASEPATH') OR exit('No direct script access allowed'); class MY_Router extends CI_Router { /** * 根据给定的URL片段获取对应的路由目标 * @param string $url 要匹配的URL(比如"novosti/petar") * @param bool $replace_placeholders 是否替换路由中的$1、$2等占位符 * @return string|null 匹配到的路由目标,无匹配则返回null */ public function get_route_target($url, $replace_placeholders = true) { // 预处理URL:去除首尾斜杠,移除可能存在的目录前缀 $url = trim($url, '/'); if (!empty($this->directory)) { $url = preg_replace('#^' . preg_quote($this->directory, '#') . '#', '', $url); } // 先检查静态路由(无正则占位符的规则) if (isset($this->routes[$url])) { return $this->routes[$url]; } // 遍历带正则的路由规则进行匹配 foreach ($this->routes as $route_pattern => $route_target) { // 跳过已经检查过的静态路由 if (strpos($route_pattern, '(:any)') === false && strpos($route_pattern, '(:num)') === false && strpos($route_pattern, '(:alpha)') === false) { continue; } // 将CI的路由占位符转换为正则表达式 $regex_pattern = str_replace( array(':any', ':num', ':alpha'), array('.+', '[0-9]+', '[a-zA-Z]+'), $route_pattern ); // 匹配当前URL与路由规则 if (preg_match('#^' . $regex_pattern . '$#', $url)) { // 根据参数决定是否替换占位符 if (!$replace_placeholders) { return $route_target; } // 替换目标中的$1、$2等捕获组 if (strpos($route_target, '$') !== false && strpos($regex_pattern, '(') !== false) { $route_target = preg_replace('#^' . $regex_pattern . '$#', $route_target, $url); } return $route_target; } } // 无匹配路由时返回null return null; } }
- 在控制器中使用这个自定义方法:
// 示例1:获取替换占位符后的目标路由 $target = $this->router->get_route_target('novosti/petar'); // 输出:Main/blog/sr/petar // 示例2:获取保留占位符的原始路由规则 $target_with_placeholder = $this->router->get_route_target('novosti/petar', false); // 输出:Main/blog/sr/$1 // 示例3:匹配静态路由 $static_target = $this->router->get_route_target('contact'); // 输出:Main/contact/en
注意事项
- 路由规则顺序:CI3的路由匹配是按规则定义的顺序进行的,先定义的规则会优先匹配,你的自定义方法也遵循这个逻辑,确保路由规则的顺序符合你的预期。
- URL预处理:方法中已经处理了基础目录前缀的情况,如果你的应用部署在子目录下,也能正常工作。
- 返回值处理:如果没有匹配到任何路由,方法会返回
null,你可以根据需求修改为返回原URL或其他默认值。
内容的提问来源于stack exchange,提问作者Dejan Dozet
相关产品推荐
相关产品推荐

