您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關PHP中Yii框架運行機制及其路由功能的示例分析的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
運行機制概述
每一次 Yii 應用開始處理 HTTP 請求時,它都會進行一個近似的流程。
用戶提交指向 入口腳本 web/index.php 的請求。
入口腳本會加載 配置數組 并創建一個 應用 實例用于處理該請求。
應用會通過 request(請求) 應用組件解析被請求的 路由。
應用創建一個 controller(控制器) 實例具體處理請求。
控制器會創建一個 action(動作) 實例并為該動作執行相關的 Filters(訪問過濾器)。
如果任何一個過濾器驗證失敗,該動作會被取消。
如果全部的過濾器都通過,該動作就會被執行。
動作會加載一個數據模型,一般是從數據庫中加載。
動作會渲染一個 View(視圖),并為其提供所需的數據模型。
渲染得到的結果會返回給 response(響應) 應用組件。
響應組件會把渲染結果發回給用戶的瀏覽器。
下面的示意圖展示了應用是如何處理一個請求的。
啟動引導(Bootstrapping)
啟動引導是指:在應用開始解析并處理新接受請求之前,一個預先準備環境的過程。啟動引導會在兩個地方具體進行:入口腳本(Entry Script) 和 應用主體(application)。
在入口腳本里,需注冊各個類庫的類文件自動加載器(Class Autoloader,簡稱自動加載器)。這主要包括通過其 autoload.php 文件加載的 Composer 自動加載器,以及通過 Yii 類加載的 Yii 自動加載器。之后,入口腳本會加載應用的 配置(configuration) 并創建一個 應用主體 的實例。
在應用主體的構造函數中,會執行以下引導工作:
調用 yii\base\Application::preInit()(預初始化)方法,配置一些高優先級的應用屬性,比如 yii\base\Application::basePath 屬性。
注冊yii\base\Application::errorHandler。
通過給定的應用配置初始化應用的各屬性。
通過調用 yii\base\Application::init()(初始化)方法,它會順次調用 yii\base\Application::bootstrap() 從而運行引導組件。
加載擴展清單文件(extension manifest file) vendor/yiisoft/extensions.php。
創建并運行各個擴展聲明的 引導組件(bootstrap components)。
創建并運行各個 應用組件 以及在應用的 Bootstrap 屬性中聲明的各個 模塊(modules)組件(如果有)。
因為引導工作必須在處理每一次請求之前都進行一遍,因此讓該過程盡可能輕量化就異常重要,請盡可能地優化這一步驟。
請盡量不要注冊太多引導組件。只有他需要在 HTTP 請求處理的全部生命周期中都作用時才需要使用它。舉一個用到它的范例:一個模塊需要注冊額外的 URL 解析規則,就應該把它列在應用的 bootstrap 屬性之中,這樣該 URL 解析規則才能在解析請求之前生效。(譯注:換言之,為了性能需要,除了 URL 解析等少量操作之外,絕大多數組件都應該按需加載,而不是都放在引導過程中。)
在生產環境中,可以開啟字節碼緩存,比如 APC,來進一步最小化加載和解析 PHP 文件所需的時間。
一些大型應用都包含有非常復雜的應用配置,它們會被分割到許多更小的配置文件中。此時,可以考慮將整個配置數組緩存起來,并在入口腳本創建應用實例之前直接從緩存中加載。
yii的入口文件
這里使用了一個第三方的配置管理插件:marcovwout,來管理Yii的配置,細節我就不說了。剩下的就是就是一些基本的全局變量設置了。往Yii::createWebApplication里面傳入配置的數組,然后調用run方法,一個web應用是不是就這么跑起來了,是的,抽象到最高層就是這樣:我往一個容器里面傳入對應的配置,然后這個應用可以基于該配置正常運行起來。
說YiiBase中的兩個比較重要的方法 (import,autoload)
這里使用了一個第三方的配置管理插件:marcovwout,來管理Yii的配置,細節我就不說了。剩下的就是就是一些基本的全局變量設置了。往Yii::createWebApplication里面傳入配置的數組,然后調用run方法,一個web應用是不是就這么跑起來了,是的,抽象到最高層就是這樣:我往一個容器里面傳入對應的配置,然后這個應用可以基于該配置正常運行起來。
路由
當入口腳本在調用 yii\web\Application::run() 方法時,它進行的第一個操作就是解析輸入的請求,然后實例化對應的控制器操作處理這個請求。該過程就被稱為引導路由(routing)。(譯注:中文里既是動詞也是名詞)
解析路由
路由引導的第一步,是把傳入請求解析為一個路由。如我們在 控制器(Controllers) 章節中所描述的那樣,路由是一個用于定位控制器操作的地址。這個過程通過 request 應用組件的 yii\web\Request::resolve() 方法實現,該方法會調用 URL 管理器 進行實質上的請求解析工作。
默認情況下,傳入請求會包含一個名為 r 的 GET 參數,它的值即被視為路由。但是如果啟用 yii\web\UrlManager::enablePrettyUrl,那么在確定請求的路由時,就會進行更多處理。具體的細節請參考 URL 的解析與生成 章節。
假使某路由最終實在無法被確定,那么 request 組件會拋出 yii\web\NotFoundHttpException 異常(譯注:大名鼎鼎的 404)。
缺省路由
如果傳入請求并沒有提供一個具體的路由,(一般這種情況多為于對首頁的請求)此時就會啟用由 yii\web\Application::defaultRoute 屬性所指定的缺省路由。該屬性的默認值為 site/index,它指向 site 控制器的 index 操作。你可以像這樣在應用配置中調整該屬性的值:
return [ // ... 'defaultRoute' => 'main/index', ];
catchAll 路由(全攔截路由)
有時候,你會想要將你的 Web 應用臨時調整到維護模式,所有的請求下都會顯示相同的信息頁。當然,要實現這一點有很多種方法。這里面最簡單快捷的方法就是在應用配置中設置下 yii\web\Application::catchAll 屬性:
return [ // ... 'catchAll' => ['site/offline'], ];
catchAll 屬性需要傳入一個數組做參數,該數組的第一個元素為路由,剩下的元素會(以名值對的形式)指定綁定于該操作的各個參數。
當設置了 catchAll 屬性時,它會替換掉所有從輸入的請求中解析出來的路由。如果是上文的這種設置,用于處理所有傳入請求的操作都會是相同的 site/offline。
創建操作
一旦請求路由被確定了,緊接著的步驟就是創建一個“操作(action)”對象,用以響應該路由。
路由可以用里面的斜杠分割成多個組成片段,舉個栗子,site/index 可以分解為 site 和 index 兩部分。每個片段都是指向某一模塊(Module)、控制器(Controller)或操作(action)的 ID。
從路由的首個片段開始,應用會經過以下流程依次創建模塊(如果有),控制器,以及操作:
設置應用主體為當前模塊。
檢查當前模塊的 yii\base\Module::controllerMap 是否包含當前 ID。如果是,會根據該表中的配置創建一個控制器對象,然后跳到步驟五執行該路由的后續片段。
檢查該 ID 是否指向當前模塊中 yii\base\Module::modules 屬性里的模塊列表中的一個模塊。如果是,會根據該模塊表中的配置創建一個模塊對象,然后會以新創建的模塊為環境,跳回步驟二解析下一段路由。
將該 ID 視為控制器 ID,并創建控制器對象。用下個步驟解析路由里剩下的片段。
控制器會在他的 yii\base\Controller::actions()里搜索當前 ID。如果找得到,它會根據該映射表中的配置創建一個操作對象;反之,控制器則會嘗試創建一個與該 ID 相對應,由某個 action 方法所定義的行內操作(inline action)。
在上面的步驟里,如果有任何錯誤發生,都會拋出 yii\web\NotFoundHttpException,指出路由引導的過程失敗了。
感謝各位的閱讀!關于“PHP中Yii框架運行機制及其路由功能的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。