CodeIgniter大应用:移除文章URL中/content/,避免影响其他控制器
我明白你遇到的问题了——想把文章URL里的/content/去掉,但改完路由后其他控制器都罢工了对吧?这是因为你写的路由规则太宽泛,把所有符合[xxx]/[xxx]格式的请求都劫持到Content控制器了,包括其他正常的控制器请求(比如/user/login这种)。
下面给你两种可行的解决方案,根据你的情况选:
方案一:用PHP逻辑动态判断(适合控制器/模块多的情况)
因为你有大量控制器和模块,一个个列出来排除太麻烦,我们可以在routes.php里加一段代码,先判断请求的URI第一段是不是真实存在的控制器/模块,只有当它不是的时候,才把请求转到Content控制器。
打开application/config/routes.php,在默认路由后面加上这段代码:
// 保留你的默认路由设置 $route['default_controller'] = '你的默认控制器'; $route['404_override'] = ''; $route['translate_uri_dashes'] = FALSE; // 如果你的URL用了连字符,改成TRUE // 自定义路由逻辑 $request_segment = isset($_SERVER['REQUEST_URI']) ? trim(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH), '/') : ''; $first_segment = explode('/', $request_segment)[0] ?? ''; // 检查是否是已存在的普通控制器 $controller_file = APPPATH . 'controllers/' . ucfirst($first_segment) . '.php'; // 检查是否是模块中的控制器(如果用了HMVC模块) $module_controller_file = APPPATH . 'modules/' . $first_segment . '/controllers/' . ucfirst($first_segment) . '.php'; // 如果第一段不是有效的控制器/模块,就路由到Content if (!empty($first_segment) && !file_exists($controller_file) && !file_exists($module_controller_file)) { // 匹配 分类/文章 的URL,转到Content的view方法(或者你原来的方法名) $route['(:any)/(:any)'] = 'content/view/$1/$2'; // 匹配单独的分类URL,转到Content的分类列表方法 $route['(:any)'] = 'content/category/$1'; }
注意:
- 把
content/view改成你实际处理文章的方法名,比如你原来的Content控制器里是用index方法处理的,就改成content/index/$1/$2 - 如果你的模块结构不同,调整
$module_controller_file的路径,确保能正确找到模块控制器文件 - 如果你的URL用了连字符(比如
top-ten-coolest-gadgets),记得把$route['translate_uri_dashes']设为TRUE,这样CodeIgniter会自动把连字符转成控制器方法里的下划线
方案二:正则排除已知控制器(适合控制器数量少的情况)
如果你的控制器数量不多,可以用正则表达式,明确排除掉那些已有的控制器,只让非控制器的请求转到Content。
比如你有User、Admin、Dashboard这几个控制器,路由可以这么写:
// 先写文章路由,排除已知控制器 $route['^(?!user|admin|dashboard)([a-z0-9-]+)/([a-z0-9-]+)$'] = 'content/view/$1/$2'; $route['^(?!user|admin|dashboard)([a-z0-9-]+)$'] = 'content/category/$1'; // 再保留默认路由 $route['default_controller'] = '你的默认控制器'; $route['404_override'] = ''; $route['translate_uri_dashes'] = TRUE;
这里的^(?!user|admin|dashboard)是正则的负向前瞻,意思是“URL的第一段不是user、admin、dashboard中的任何一个”,这样就不会干扰这些控制器的正常访问了。
最后要注意的点
- 路由规则是从上到下匹配的,所以一定要把文章的路由规则放在默认路由和其他控制器的路由规则前面,否则会被后面的规则覆盖
- 测试的时候,先访问一个正常的控制器URL(比如
example.com/user),确认能正常打开;再访问文章URL(example.com/gadgets/top-ten-coolest-gadgets-of-2018),确认能正确加载文章内容 - 如果你的Content控制器里原来的方法是接受两个参数,确保方法参数顺序正确(先分类名,再文章名)
内容的提问来源于stack exchange,提问作者Francisco Manrique
相关产品推荐
相关产品推荐

