Как установить динамический маршрут для использования slug в CodeIgniter?

Предположим, что у меня есть контроллер с именем

страницы

и существует способ

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-article или http://localhost/another-article-blablabla

Как это сделать и не нарушать другие маршруты, например $route['friends'] = 'users'; или $route['about-us'] = 'pages/about_us'; ?

Потому что, если я это делаю: $route['(:any)'] = 'pages/slug_on_the_fly/$1';

Вероятно, это разрушит все остальное или?

Urls маршрутизируются в следующем порядке:

  1. Явные маршруты в $route (routes.php) проверяются по порядку .
  2. [folder/]controller/methodname/args... маршрут [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' 

Регулярное выражение здесь означает «любой URL-адрес, который не имеет косых черт (кроме, может быть, последнего)». Вы можете уточнить это, чтобы описать свой формат slug, если у вас есть другие ограничения. (Хороший – [a-z0-9-]+ .) Если ваш контроллер обнаруживает пулю в db, все готово. Если это не так, оно должно служить 404.

Тем не менее, вы отказываетесь от возможности какой-либо неявной маршрутизации, поскольку Codeigniter не предоставляет никакого способа, чтобы контроллер «отказался» от маршрута назад к маршрутизатору. Например, если у вас есть контроллер с именем 'foo', и вы хотите, чтобы URL-адрес, например /foo направлялся в Foo::index() , вы должны добавить явный маршрут для этого случая, потому что он будет пойман по этому маршруту и ​​отправлен на Pages::slug_on_the_fly('foo') . В общем, у вас не должно быть пули, которые также являются именами классов контроллера! Вот почему у вас должно быть очень небольшое количество этих url-slugs, если у вас их вообще есть!

Если у вас есть и большое количество этих явных маршрутов, и вы не согласны соблюдать эти неявные ограничения маршрутизации, вы можете попытаться добавить их в $route динамически:

  1. Создайте файл routes_extra.php который routes.php в конце. Напишите новые маршруты для него как часть сохранения страницы или при создании / развертывании сайта.
  2. Подкласс Router.php и добавьте новый слой маршрутизации.
  3. Добавьте крюк pre_system который добавляет маршруты.

Я уверен, что есть другие способы.

Вы можете использовать маршруты, управляемые базой данных.

Добавьте таблицу 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'); 

Используйте резервный контроллер / метод зарезервированного маршрута 404 . Если действительный контроллер / маршрут не существует, этот метод будет вызван. Прекрасно работает как уловка.

Предположим, у вас есть 3 контроллера, кроме контроллера страниц, которые говорят контроллер 1, контроллер 2 и контроллер3,

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