路由和URL生成
當一個YII應用開始處理一個請求的時候,它首先要做的便是將請求的URL轉化成一個路由。路由的作用是用於后續實例化相應的控制器和操作,以便處理請求,整個處理過程便叫做路由。路由的逆過程叫做URL生成,是指用給定的路由和參數信息來生成一個URL。當使用生成的URL來發出請求的時候,路由處理的過程又能夠再次將其解析還原出原始的路由和參數信息。
主要負責路由和URL生成工作的是URL管理器,其被注冊成為應用組件。URL管理器提供方法parseRequest()來解析請求,解析出其中的路由和參數信息。而方法 createUrl() 用於將給定的路由和參數信息,生成一個URL。通過在應用配置中配置URL管理器,可以讓你的應用能夠識別任意的URL格式,而不用修改已有程序代碼。例如,你能使用如下的代碼來生成一個URL。
use yii\helpers\Url; // Url::to() calls UrlManager::createUrl() to create a URL
$url = Url::to(['post/view', 'id' => 100]);
取決於URL管理器的配置,如上代碼生成的URL的樣子看上去像下面這樣的。假如這個URL后續被請求的話,它將被解析成上面的原始路由和參數信息。
/index.php?r=post/view&id=100
/index.php/post/100
/posts/100
URL格式
URL管理器支持兩種URL格式:默認URL格式和漂亮URL格式。默認URL格式使用一個查詢參數r傳遞路由,其他參數按照正常方式放在URL中。例如,URL /index.php?r=post/view&id=100 的路由為post/view和參數id為100。默認URL格式並不要求對URL管理器做任何配置。漂亮URL格式是使用額外的路徑跟在入口腳本名之后,來展現路由和相關參數的。例如,URL /index.php/post/100的額外路徑為/post/100,其展現出的路由為post/view和參數id為100。如果要使用這種URL格式,你需要根據實際需求,設計一個URL規則集。你可以通過修改URL管理器中屬性enablePrettyUrl的值,來達到在這兩種URL格式之間切換的目的。
路由
路由的工作可以分為兩步:
1.從請求中解析出一個路由和相關參數;
2.根據路由生成響應的控制器操作,來處理該請求。
當使用默認URL格式的時候,解析出路由很簡單,只要獲取參數r的值便可;
當使用漂亮URL格式的時候,URL管理器會檢測URL規則集,從中找出與該請求匹配的路由。如果找不到規則與之匹配,將會拋出異常yii\web\NotFoundHttpException。
一旦從請求中解析出路由,接下來要做的就是創建與該路由相關的控制器操作。路由被斜線切割成幾個部分,例如,site/index會被切割成site和index。每個部分都是一個ID,它們也許指向模塊、控制器或操作。從路由的第一個部分開始,應該會執行如下幾步來創建模塊(如果有的話)、控制器和操作:
1.設置應用主體為當前模塊。
2.檢查當前模塊的 yii\base\Module::controllerMap 是否包含當前ID。如果是,會根據該表中的配置創建一個控制器對象,然后跳到步驟五執行該路由的后續片段。
3.檢查該 ID 是否指向當前模塊中 yii\base\Module::modules 屬性里的模塊列表中的一個模塊。如果是,會根據該模塊表中的配置創建一個模塊對象,然后會以新創建的模塊為環境,跳回步驟二解析下一段路由。
4.將該 ID 視為控制器 ID,並創建控制器對象。用下個步驟解析路由里剩下的片段。
5.控制器會在他的 yii\base\Controller::actions()里搜索當前 ID。如果找得到,它會根據該映射表中的配置創建一個操作對象;反之,控制器則會嘗試創建一個與該 ID 相對應,由某個 action 方法所定義的行內操作(inline action)。
上面這些步驟中,如果有任何錯誤發生,應用都會拋出異常yii\web\NotFoundHttpException,意味着路由處理失敗。
默認路由
當一個請求沒有找到匹配的路由的時候,所謂的默認路由將會被代替使用。默認情況下,默認路由為site/index,其指向控制器site下面的操作index。你也可以通過修改應用配置中屬性defaultRoute來指定它,就像下面這樣:
[ // ...
'defaultRoute' => 'main/index', ];
catchAll 路由
當你的應用處於臨時維護狀態下時,你也許希望對於所有的請求,應用都顯示相同的頁面。有很多方法來實現這個目標,最簡單的方法之一便是在應用配置中配置屬性yii\web\Application::$catchAll,像下面這樣。
[ // ...
'catchAll' => ['site/offline'], ];
創建鏈接
YII提供了一個幫助方法yii\helpers\Url::to(),根據提供的路由和參數信息去生成各種URL,如下是一些例子:
use yii\helpers\Url; // creates a URL to a route: /index.php?r=post/index echo Url::to(['post/index']); // creates a URL to a route with parameters: /index.php?r=post/view&id=100 echo Url::to(['post/view', 'id' => 100]); // creates an anchored URL: /index.php?r=post/view&id=100#content echo Url::to(['post/view', 'id' => 100, '#' => 'content']); // creates an absolute URL: http://www.example.com/index.php?r=post/index echo Url::to(['post/index'], true); // creates an absolute URL using the https scheme: https://www.example.com/index.php?r=post/index echo Url::to(['post/index'], 'https');
注意,上面的例子是基於默認URL模式是開啟狀態的。如果漂亮URL模式被啟動的話,上面創建的URL會有所不同,取決於使用的URL路由。
傳遞給方法 yii\helpers\Url::to()的路由信息是和上下文有關的,它可以是相對路徑,也可以是絕對路徑,可以根據下面的規則來標准化:
1. 如果路由傳遞的是空字符串,當前請求的路由將被使用;
2. 如果路由不包含任何斜杠(\),它會被認為是當前控制器的某個操作的ID,它將會被前置當前路由唯一ID;
3. 如果路由不以斜杠(\)打頭,它會被認為是相對於當前模塊的路由,它將會被前置當前模塊的唯一ID。
=================================
未完待續。。。今日查看YII框架的中文文檔,點擊其中包含的某個鏈接竟然報錯,被迫去其英文支持站點搜索相關文檔,對比發現:中文文檔有些內容可能有刪節。於是,便想在閱讀英文文檔的時候,順便做個翻譯,給后來者一些便利,不知道這樣做是否有意義?同時由於英文水平有限,翻譯過程中難免有不足之處,還請大家多多拍磚...
原文網址:http://www.yiiframework.com/doc-2.0/guide-runtime-routing.html