2013-03-12 107 views
3

比方說,我有一個名爲控制器如何設置動態路由在CodeIgniter中使用slug?

,有一個方法

slug_on_the_fly

public function slug_on_the_fly($slug)

頁如何將我這個樣子路線?

E.g.對於博客控制器就會很容易:

$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';

這可能會毀掉一切還是?

+0

任何想法如何路由這種情況? – Derfder 2013-03-12 17:00:15

+0

將「catch-all」路由放到最後,並確保該方法使用'error_404()',如果它找不到任何東西。 – 2013-03-12 17:16:06

+0

你能更具體嗎?如果我把'$ route ['(:any)'] ='pages/slug_on_the_fly/$ 1';'最後所有的東西都會被擰緊 – Derfder 2013-03-12 17:50:11

回答

6

URL被路由以下列順序:

  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' 

這裏的正則表達式的意思是 「一個沒有斜槓(也許除了最後一個)的任何URL」。如果您有任何其他限制,您可以優化它以描述您的slu format格式。 (好的一個是[a-z0-9-]+。)如果你的控制器在數據庫中發現了子彈,你就完成了。如果沒有,它必須服務一個404.

但是,您放棄了一些隱式路由的可能性,因爲Codeigniter不提供任何方式讓控制器「放棄」返回路由器的路由。例如,如果您有一個名爲'foo'的控制器,並且您希望像/foo這樣的網址路由到Foo::index(),則必須爲此情況添加顯式路由,因爲它將被此路由捕獲併發送到Pages::slug_on_the_fly('foo')一般來說,你不應該有也是控制器類名稱的slu!!這就是爲什麼你應該只有很少的這些url-slugs,如果你有任何的!

如果你有大量的這些顯式路由的你不願意被這些隱路由限制裏面,你可以嘗試將其添加到$route動態:

  1. 做一個routes_extra.php其中routes.php包括在最後的文件。作爲保存頁面或構建/部署網站的一部分,向其寫入新路線。
  2. 子類Router.php並添加一個新的路由層。
  3. 添加一個添加路線的pre_system掛鉤。

我確定還有其他方法。

+0

謝謝,我使用HMVC與codeigniter和'$ route ['([^ /] +)/?'] ='pages/slug_on_the_fly/$ 1''似乎在工作。但我需要做更多的測試。現在,謝謝。 – Derfder 2013-03-12 19:58:49

1

讓我們假設你有超過網頁控制其他3個控制器說控制器1,控制器2和controller3然後,

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

你可以使用數據庫驅動的路線。

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'); 
+0

謝謝,interresting概念。但是當我有例如10 000篇文章。這會很慢或沒有?在我看來,這不是什麼大問題。我有最大值。 50頁/文章。但我只是好奇;) – Derfder 2013-03-12 18:54:45

+0

你可以緩存數據庫查詢輸出。我使用了這個擴展版本來處理我所有的路由,從緩存中讀取的文件速度很好(對我來說)。我使用https://github.com/philsturgeon/codeigniter-cache – Rooneyl 2013-03-12 19:00:56

3

使用404 override reserved route控制器/方法。如果有效的控制器/路由不存在,則會調用此方法。作爲一個全面的工作很好。

0

也許這會幫助你。

$route['controllerName/([^/]+)/([^/]+)'] = "index/author/$1/$2";