路由和URL生成
當(dāng)一個(gè)YII應(yīng)用開始處理一個(gè)請(qǐng)求的時(shí)候,它首先要做的便是將請(qǐng)求的URL轉(zhuǎn)化成一個(gè)路由。路由的作用是用于后續(xù)實(shí)例化相應(yīng)的控制器和操作,以便處理請(qǐng)求,整個(gè)處理過(guò)程便叫做路由。? ? ? ? ? ? ? ? ? ? ?(推薦學(xué)習(xí):yii框架)
路由的逆過(guò)程叫做URL生成,是指用給定的路由和參數(shù)信息來(lái)生成一個(gè)URL。當(dāng)使用生成的URL來(lái)發(fā)出請(qǐng)求的時(shí)候,路由處理的過(guò)程又能夠再次將其解析還原出原始的路由和參數(shù)信息。
主要負(fù)責(zé)路由和URL生成工作的是URL管理器,其被注冊(cè)成為應(yīng)用組件。URL管理器提供方法parseRequest()來(lái)解析請(qǐng)求,解析出其中的路由和參數(shù)信息。
而方法 createUrl() 用于將給定的路由和參數(shù)信息,生成一個(gè)URL。通過(guò)在應(yīng)用配置中配置URL管理器,可以讓你的應(yīng)用能夠識(shí)別任意的URL格式,而不用修改已有程序代碼。例如,你能使用如下的代碼來(lái)生成一個(gè)URL。
use?yiihelpersUrl; //?Url::to()?calls?UrlManager::createUrl()?to?create?a?URL $url?=?Url::to(['post/view',?'id'?=>?100]);
取決于URL管理器的配置,如上代碼生成的URL的樣子看上去像下面這樣的。假如這個(gè)URL后續(xù)被請(qǐng)求的話,它將被解析成上面的原始路由和參數(shù)信息。
/index.php?r=post/view&id=100 /index.php/post/100 /posts/100
URL格式?
URL管理器支持兩種URL格式:默認(rèn)URL格式和漂亮URL格式。默認(rèn)URL格式使用一個(gè)查詢參數(shù)r傳遞路由,其他參數(shù)按照正常方式放在URL中。
例如,URL /index.php?r=post/view&id=100 的路由為post/view和參數(shù)id為100。默認(rèn)URL格式并不要求對(duì)URL管理器做任何配置。
漂亮URL格式是使用額外的路徑跟在入口腳本名之后,來(lái)展現(xiàn)路由和相關(guān)參數(shù)的。
例如,URL /index.php/post/100的額外路徑為/post/100,其展現(xiàn)出的路由為post/view和參數(shù)id為100。
如果要使用這種URL格式,你需要根據(jù)實(shí)際需求,設(shè)計(jì)一個(gè)URL規(guī)則集。你可以通過(guò)修改URL管理器中屬性enablePrettyUrl的值,來(lái)達(dá)到在這兩種URL格式之間切換的目的。
路由
路由的工作可以分為兩步:
1.從請(qǐng)求中解析出一個(gè)路由和相關(guān)參數(shù);
2.根據(jù)路由生成響應(yīng)的控制器操作,來(lái)處理該請(qǐng)求。
當(dāng)使用默認(rèn)URL格式的時(shí)候,解析出路由很簡(jiǎn)單,只要獲取參數(shù)r的值便可;
當(dāng)使用漂亮URL格式的時(shí)候,URL管理器會(huì)檢測(cè)URL規(guī)則集,從中找出與該請(qǐng)求匹配的路由。如果找不到規(guī)則與之匹配,將會(huì)拋出異常yiiwebNotFoundHttpException。
一旦從請(qǐng)求中解析出路由,接下來(lái)要做的就是創(chuàng)建與該路由相關(guān)的控制器操作。路由被斜線切割成幾個(gè)部分,例如,site/index會(huì)被切割成site和index。
每個(gè)部分都是一個(gè)ID,它們也許指向模塊、控制器或操作。從路由的第一個(gè)部分開始,應(yīng)該會(huì)執(zhí)行如下幾步來(lái)創(chuàng)建模塊(如果有的話)、控制器和操作:
1.設(shè)置應(yīng)用主體為當(dāng)前模塊。
2.檢查當(dāng)前模塊的 yiibaseModule::controllerMap 是否包含當(dāng)前ID。如果是,會(huì)根據(jù)該表中的配置創(chuàng)建一個(gè)控制器對(duì)象,然后跳到步驟五執(zhí)行該路由的后續(xù)片段。
3.檢查該 ID 是否指向當(dāng)前模塊中 yiibaseModule::modules 屬性里的模塊列表中的一個(gè)模塊。如果是,會(huì)根據(jù)該模塊表中的配置創(chuàng)建一個(gè)模塊對(duì)象,然后會(huì)以新創(chuàng)建的模塊為環(huán)境,跳回步驟二解析下一段路由。
4.將該 ID 視為控制器 ID,并創(chuàng)建控制器對(duì)象。用下個(gè)步驟解析路由里剩下的片段。
5.控制器會(huì)在他的 yiibaseController::actions()里搜索當(dāng)前 ID。如果找得到,它會(huì)根據(jù)該映射表中的配置創(chuàng)建一個(gè)操作對(duì)象;反之,控制器則會(huì)嘗試創(chuàng)建一個(gè)與該 ID 相對(duì)應(yīng),由某個(gè) action 方法所定義的行內(nèi)操作(inline action)。
上面這些步驟中,如果有任何錯(cuò)誤發(fā)生,應(yīng)用都會(huì)拋出異常yiiwebNotFoundHttpException,意味著路由處理失敗。