5

Let's say that I have a controller named

pages

and there is a method

slug_on_the_fly

public function slug_on_the_fly($slug)

How would my route for this look like?

E.g. for blog controller it would be easy:

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

and then http://localhost/blog/name-of-the-article works nice

However, what if I want to do it like without blog so e.g.

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

How to do it and don't break another routes e.g. $route['friends'] = 'users'; or $route['about-us'] = 'pages/about_us'; ?

Because if I do: $route['(:any)'] = 'pages/slug_on_the_fly/$1';

It will probably ruin everything else or?

4

6 回答 6

8

网址按以下顺序路由:

  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]+。)

如果您有大量此类路由(可能不是一个好主意,顺便说一句!),您可以在末尾添加一个通配符路由$route

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

此处的正则表达式表示“任何没有斜杠的网址(可能最后一个除外)”。如果您有任何其他限制,您可以改进它以描述您的 slug 格式。(一个很好的是[a-z0-9-]+。)如果你的控制器在数据库中找到了 slug,你就完成了。如果没有,它必须提供 404。

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

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

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

我敢肯定还有其他方法。

于 2013-03-12T19:48:28.273 回答
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');
于 2013-03-12T18:45:48.613 回答
3

使用404 覆盖保留路由控制器/方法。如果不存在有效的控制器/路由,则将调用此方法。作为一个包罗万象的作品很棒。

于 2013-03-13T06:30:47.973 回答
0

假设你有 3 个控制器,而不是页面控制器,比如控制器 1、控制器 2 和控制器 3,然后,

$route['^(?!controller1|controller2|controller3).*'] = 'pages/slug_on_the_fly/$1';;
于 2013-03-12T17:12:18.657 回答
0

也许这会对你有所帮助。

$route['controllerName/([^/]+)/([^/]+)'] = "index/author/$1/$2";
于 2018-03-01T09:24:20.617 回答
0

这可以帮助你

$route['controllerName/(:any)] = "controllename/method/slug";

于 2020-01-30T15:39:22.810 回答