如何在CodeIgniter中设置动态路由以使用slug?

问题描述 投票:5回答:5

假设我有一个名为的控制器

网页

并且有一种方法

slug_on_the_fly

public function slug_on_the_fly($slug)

我的路线怎么样?

例如。对于博客控制器来说很简单:

$route['blog/(:any)'] = 'pages/slug_on_the_fly/$1';

然后http://localhost/blog/name-of-the-article很好

但是,如果我想这样做就像没有blog那样,例如

http://localhost/name-of-the-articlehttp://localhost/another-article-blablabla

怎么做,不要破坏其他路线,例如$route['friends'] = 'users';$route['about-us'] = 'pages/about_us';

因为如果我这样做:$route['(:any)'] = 'pages/slug_on_the_fly/$1';

它可能会破坏其他一切或?

php codeigniter url-rewriting url-routing
5个回答
7
投票

网址按以下顺序排列:

  1. $route(routes.php)中的显式路线将按顺序进行检查。
  2. 尝试隐式路由[folder/]controller/methodname/args...作为后备。

如果有少量已知的显式路由,您只需将它们添加到$route

$route['(my-slug|my-other-slug|my-third-slug)'] = 'pages/slug_on_the_fly/$1'

(路由键实际上被解析为正则表达式,:any:num被重写为.+[0-9]+。)

如果你有大量的这样的路线(可能不是一个好主意,BTW!)你可以添加一个通配路线到$route的末尾:

$route['([^/]+)/?'] = 'pages/slug_on_the_fly/$1'

这里的正则表达式意味着“任何没有斜线的网址(除了最后一个)”。如果您有任何其他限制,可以对其进行优化以描述您的slug格式。 (好的一个是[a-z0-9-]+。)如果你的控制器在db中找到了slug,你就完成了。如果没有,它必须服务404。

但是,您放弃了一些隐式路由的可能性,因为Codeigniter没有为控制器提供任何方式“放弃”路由回路由器。例如,如果你有一个名为'foo'的控制器,你想要一个像/foo这样的网址路由到Foo::index(),你必须为这种情况添加一个显式路由,因为它会被这条路由捕获并发送到Pages::slug_on_the_fly('foo')。一般来说,你不应该有slugs也是控制器类名!这就是为什么你应该拥有极少数这些url-slugs,如果你有任何!

如果您同时拥有大量这些显式路由并且您不愿意遵守这些隐式路由限制,则可以尝试动态地将它们添加到$route

  1. 制作routes_extra.php文件,routes.php包含在最后。在保存页面或构建/部署站点时,将新路由写入其中。
  2. 子类Router.php并添加一个新的路由层。
  3. 添加一个添加路线的pre_system钩子。

我相信还有其他方法。


6
投票

您可以使用数据库驱动的路由。

将表blog_slugs添加到MySQL数据库:

CREATE TABLE IF NOT EXISTS `blog_slugs` (
  `id` bigint(20) NOT NULL auto_increment,
  `slug` varchar(192) collate utf8_unicode_ci NOT NULL
  PRIMARY KEY  (`id`),
  KEY `slug` (`slug`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1;

将application / config / routes.php中的代码替换为下面的代码:

$route[ 'default_controller' ]  = 'main';
$route[ '404_override' ]        = 'error404';

require_once( BASEPATH .'database/DB'. EXT );
$db =& DB();
$query = $db->get( 'blog_slugs' );
$result = $query->result();
foreach( $result as $row )
{
    $route[ $row->slug ] = 'pages/slug_on_the_fly/$1;
}

您所要做的就是在创建博客条目时创建记录并完成:

INSERT INTO `blog_slugs` (`slug`) VALUES ('name-of-the-article');

3
投票

使用404 override reserved route控制器/方法。如果不存在有效的控制器/路由,则将调用此方法。作为一个包罗万象的工作非常好。


1
投票

假设你有3个控制器,而不是页面控制器说controller1,controller2和controller3然后,

$route['^(?!controller1|controller2|controller3).*'] = 'pages/slug_on_the_fly/$1';;

0
投票

也许这会对你有所帮助。

$route['controllerName/([^/]+)/([^/]+)'] = "index/author/$1/$2";
© www.soinside.com 2019 - 2024. All rights reserved.