Как установить динамический маршрут для использования слаг в 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';
Это вероятно разрушит все остальное или?
5 ответов
URL-адреса маршрутизируются в следующем порядке:
- Явные маршруты в
$route
(rout.php) проверяются по порядку. - Неявный маршрут
[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'
Регулярное выражение здесь означает "любой URL, который не имеет косой черты (кроме, может быть, последнего)". Вы можете уточнить это, чтобы описать ваш формат слагов, если у вас есть другие ограничения. (Хороший [a-z0-9-]+
.) Если ваш контроллер обнаружит слизняк в БД, все готово. Если это не так, он должен служить 404.
Однако вы отказываетесь от возможности некоторой неявной маршрутизации, поскольку Codeigniter не предоставляет контроллеру никакого способа "отказаться" от маршрута обратно к маршрутизатору. Например, если у вас есть контроллер с именем 'foo', и вы хотите URL, как /foo
направить в Foo::index()
, вы должны добавить явный маршрут для этого случая, потому что он будет перехвачен этим маршрутом и отправлен Pages::slug_on_the_fly('foo')
вместо. В общем, вы не должны иметь слагов, которые также являются именами классов контроллеров! Вот почему у вас должно быть очень небольшое количество этих URL-слагов, если они вообще есть!
Если у вас имеется большое количество этих явных маршрутов, и вы не готовы соблюдать эти неявные ограничения маршрутизации, вы можете попробовать добавить их в $route
динамически:
- Делать
routes_extra.php
файл которыйroutes.php
включает в конце. Запишите новые маршруты к нему как часть сохранения страницы или при создании / развертывании сайта. - Подкласс
Router.php
и добавьте новый слой маршрутизации. - Добавить
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/rout.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 переопределенный зарезервированный контроллер маршрута / метод. Если действующий контроллер / маршрут не существует, будет вызван этот метод. Прекрасно работает в качестве универсального.
Может быть, это поможет вам.
$route['controllerName/([^/]+)/([^/]+)'] = "index/author/$1/$2";
Давайте предположим, что у вас есть 3 контроллера, кроме страниц контроллера, скажем, контроллер1, контроллер2 и контроллер3 тогда,
$route['^(?!controller1|controller2|controller3).*'] = 'pages/slug_on_the_fly/$1';;
Это может вам помочь
$route['controllerName/(:any)] = "controllename/method/slug";