URI 路由

一般說來,在URL字串與對應的控制器(controller)class/function 之間有著一對一的關係。 通常這些在 URI 中的片段會遵照下列的模式::

example.com/class/function/id/

不過在一些實例中,你可能想要重新映射這個關係好讓不同的 class/function 可以被呼叫,而不是原本對應到 URL 的 class/function。

例如,假設你要讓你的 URL 有以下的形式:

example.com/product/1/
example.com/product/2/
example.com/product/3/
example.com/product/4/

正常狀況下,URL的第二片段是保留給函數名稱,但是在上例中,它卻含有 product ID。 為了克服這個狀況,CodeIgniter 允許你重新對應 URL handler。

設定你自己的路由規則

路由規則定義在你的 application/config/routes 。你可以在裡面看到一個叫做 $route 的陣列,它允許你指定你自己的路由標準。路由可以用萬用字元或是正規式來指定。

萬用字元

一個典型的萬用字元路由看起來會像這樣:

$route['product/:num'] = 'catalog/product_lookup';

在一個路由中,陣列的 key 包含了要被匹配的 URI,而陣列值則包含要被重導的目標。 在上例中,如果“product”這個字在 URL 的第一片段,而且第二片段是數字,則轉而使用“catalog”類別以及“product_lookup”方法。

你可以用文字的值或是兩種萬用字元來匹配:

(:num) 將匹配只含有數字的一個片段。 (:any) 將匹配含有任何字元的一個片段(除了 ‘/’,這是區段界定符號)。

Note

萬用字元實際上是正規表達式的別名, :any 被翻譯成 [^/]+ 以及 :num 被翻譯成 [0-9]+

Note

路由將依照被定義的順序去路由。 較優先的路由總是會優先於較後的路由。

Note

路由規則不是過濾器!設定規則像是 e.g. ‘foo/bar/(:num)’ 如果這是一個有效的路徑,不會防止控制器 Foo 以及方法 bar 被非數字的直呼叫。

例子

這裡有幾個路由的範例:

$route['journals'] = 'blogs';

一個在第一片段包含“journals”這個字的 URL,將被重新對應到”blogs“類別。

$route['blog/joe'] = 'blogs/users/34';

一個包含“blog/joe”片段的URL,將重新對應到”blogs“類別以及“users”方法。ID 將會設定成”34“。

$route['product/(:any)'] = 'catalog/product_lookup';

一個在第一片段是“product”而在第二片段是任何值的 URL,將重新對應到“catalog”類別以及“product_lookup”方法。

$route['product/(:num)'] = 'catalog/product_lookup_by_id/$1';

一個在第一片段為“product”而第二片段是任何數字的 URL 將重新對應到“catalog”類別以及“product_lookup_by_id”方法,匹配的數字將傳給這個函數作為變數。

Important

不要在開頭/結尾使用斜線。

正規表達式

如果你偏好使用正規表達式來定義路由規則,任何合法的正規式都允許使用,包括 back-reference。

Note

如果使用 back-reference,你必須使用 $ 語法而不是 \ 語法。

一個典型的正規表達式路由可能看起來像這樣::

$route['products/([a-z]+)/(\d+)'] = '$1/id_$2';

在上例中,一個像 products/shirts/123 的 URL 會轉而呼叫“shirts”控制器(Controller)類別及 id_123 函數。

使用正規表達式,你也可以一次分隔多個區段的內容。

例如,如果使用者想存取你的 Web 應用程式被保護區域的密碼,在登入之後,你希望重導向它們回其他頁面, 你可以參考以下有用的範例:

$route['login/(.+)'] = 'auth/login/$1';

這些對於你不了解正規表達式,並且希望學習更多關於正規表達式,參考 regular-expressions.info <http://www.regular-expressions.info/> 可能是一個良好的啟點。

Note

你也可以使用正規表達式時混合以及匹配萬用字元。

回調

你可以使用回調函數來取代一般的路由規則來處理 back-references。例子:

$route['products/([a-zA-Z]+)/edit/(\d+)'] = function ($product_type, $id)
{
        return 'catalog/product_edit/' . strtolower($product_type) . '/' . $id;
};

路由中使用 HTTP 動詞

這是有可能的使用 HTTP 動詞(request method)去定義你的路由規則。 這是特別有用的當建立 RESTful 應用程式的時後。你可以使用標準的 HTTP 動詞(GET、PUT、POST、DELETE、PATCH)或者客製化的動詞像是(e.g. PURGE)。HTTP 動詞規則不區分大小寫。所有你需要做的路由,就是將動詞增加到你的陣列索引裡面。

例如:

$route['products']['put'] = 'product/insert';

上述例子,PUT 請求到 URI“products” 稱之為 Product::insert() 控制器方法。

$route['products/(:num)']['DELETE'] = 'product/delete/$1';

DELETE 請求到 URL“products”第一個片段,數字在第二個片段將會重新映射到 Product::delete() 方法,傳入數值到第一個參數上。

使用 HTTP 動詞當然是可選的(非必要)。

保留的路由

這裏有三個保留的路由:

$route['default_controller'] = 'welcome';

這個路由指定在 URI 裡沒有任何資料時要載入哪個控制器(Controller)類別,人們載入根 URL 時就是這個情況。在上例中,“welcome”類別將被載入。你要儘量有一個預設路由,否則預設會出現一個 404 頁面。

$route['404_override'] = '';

這個路由指定控制器類別應該被載入,如果請求控制器找不到的時候。 它將會複寫預設的 404 錯誤頁面。 Same per-directory rules as with ‘default_controller’ apply here as well. 這不會影響 show_404() 函數,將依舊載入預設 error_404.php 檔案在 application/views/errors/error_404.php

$route['translate_uri_dashes'] = FALSE;

很顯然這是布林值,這不是真的路由。 這個選項使你自動地在控制器的方法中 URI 片段將底線替換掉破折號(’-‘),如果你需要做成這樣,從而節省您更多的路由項目。 這是必須的,因為破折號不是有效得類別或者方法名稱字元,如果你使用破折號,會導致重大錯誤。