YII 的源碼分析(三)
前面已經看完了啟動一個yii程式所要經過的流程,以及渲染一個頁面是怎麼完成的。今天要分析的是yii是如何處理使用者請求的。也就是控制和動作部分。
還是以helloworld為例示範此過程。我們在網址列輸入http://localhost/study/yii/demos/helloworld/index.php,頁面顯示了hello world.
前面的分析都是用的預設值,但是如果url有參數的時候,yii又是怎麼處理的呢?帶著這個問題,我們具體來分析一下。
在CWebApplication中有這樣一行程式碼:
<span>$route</span>=<span>$this</span>->getUrlManager()->parseUrl(<span>$this</span>->getRequest());
這就是傳說中的路由了,是不是有點小雞凍呢?先看看getUrlManager是個神馬。
<span>public</span> <span>function</span><span> getUrlManager() { </span><span>return</span> <span>$this</span>->getComponent('urlManager'<span>); }</span>
這個又要透過找關係了.
<span>public</span> <span>function</span> getComponent(<span>$id</span>,<span>$createIfNull</span>=<span>true</span><span>) { </span><span>if</span>(<span>isset</span>(<span>$this</span>->_components[<span>$id</span><span>])) </span><span>return</span> <span>$this</span>->_components[<span>$id</span><span>]; </span><span>elseif</span>(<span>isset</span>(<span>$this</span>->_componentConfig[<span>$id</span>]) && <span>$createIfNull</span><span>) { </span><span>$config</span>=<span>$this</span>->_componentConfig[<span>$id</span><span>]; </span><span>if</span>(!<span>isset</span>(<span>$config</span>['enabled']) || <span>$config</span>['enabled'<span>]) { Yii</span>::trace("Loading \"<span>$id</span>\" application component",'system.CModule'<span>); </span><span>unset</span>(<span>$config</span>['enabled'<span>]); </span><span>$component</span>=Yii::createComponent(<span>$config</span><span>); </span><span>$component</span>-><span>init(); </span><span>return</span> <span>$this</span>->_components[<span>$id</span>]=<span>$component</span><span>; } } }</span>
執行了return $this->_components[$id]; id就是傳進去的urlManager,其實從這裡也還看不出什麼,直接找到urlManager這個類,看parseUrl:
<span>public</span> <span>function</span> parseUrl(<span>$request</span><span>) { </span><span>if</span>(<span>$this</span>->getUrlFormat()===self::<span>PATH_FORMAT) { </span><span>$rawPathInfo</span>=<span>$request</span>-><span>getPathInfo(); </span><span>$pathInfo</span>=<span>$this</span>->removeUrlSuffix(<span>$rawPathInfo</span>,<span>$this</span>-><span>urlSuffix); </span><span>foreach</span>(<span>$this</span>->_rules <span>as</span> <span>$i</span>=><span>$rule</span><span>) { </span><span>if</span>(<span>is_array</span>(<span>$rule</span><span>)) </span><span>$this</span>->_rules[<span>$i</span>]=<span>$rule</span>=Yii::createComponent(<span>$rule</span><span>); </span><span>if</span>((<span>$r</span>=<span>$rule</span>->parseUrl(<span>$this</span>,<span>$request</span>,<span>$pathInfo</span>,<span>$rawPathInfo</span>))!==<span>false</span><span>) </span><span>return</span> <span>isset</span>(<span>$_GET</span>[<span>$this</span>->routeVar]) ? <span>$_GET</span>[<span>$this</span>->routeVar] : <span>$r</span><span>; } </span><span>if</span>(<span>$this</span>-><span>useStrictParsing) </span><span>throw</span> <span>new</span> CHttpException(404,Yii::t('yii','Unable to resolve the request "{route}".', <span>array</span>('{route}'=><span>$pathInfo</span><span>))); </span><span>else</span> <span>return</span> <span>$pathInfo</span><span>; } </span><span>elseif</span>(<span>isset</span>(<span>$_GET</span>[<span>$this</span>-><span>routeVar])) </span><span>return</span> <span>$_GET</span>[<span>$this</span>-><span>routeVar]; </span><span>elseif</span>(<span>isset</span>(<span>$_POST</span>[<span>$this</span>-><span>routeVar])) </span><span>return</span> <span>$_POST</span>[<span>$this</span>-><span>routeVar]; </span><span>else</span> <span>return</span> ''<span>; }</span>
從上面的程式碼來看,如果我們不在url上傳點東西,直接就return ''了。於是問題來了,參數要怎麼傳呢?
isset($_GET[$this-><span>routeVar]) <br></span>
<span>public</span> <span>$routeVar</span>='r';
於是有辦法了,讓我們一起來使點壞吧。加上這樣的一個參數helloworld/index.php?r=abc
發現報錯了。說明abc這個控制器是不存在的,事實上也是不存在的,使點小壞壞而已,正所謂男人不壞,女人不愛。
改成helloworld/index.php?r=site就可以顯示hello world了,這是什麼鬼原理呢?原因很簡單,因為定義了site控制器嘛。
<span>class</span> SiteController <span>extends</span><span> CController { </span><span>/*</span><span>* * Index action is the default action in a controller. </span><span>*/</span> <span>public</span> <span>function</span><span> actionIndex() { </span><span>echo</span> 'Hello World'<span>; }</span><span> }</span>
好吧,這個我沒有意見,但是actionIndex又是神麼鬼?在yii中,這稱為動作。它捕獲的是控制器後面的參數,如果我們輸?r=site/index就是index,動作是用“/"進行分隔的,為了驗正一下我說的不是騙女孩子的鬼話,我在site控制器裡加一個動作給你看:
<span>class</span> SiteController <span>extends</span><span> CController { </span><span>/*</span><span>* * Index action is the default action in a controller. </span><span>*/</span> <span>public</span> <span>function</span><span> actionIndex() { </span><span>echo</span> 'Hello World'<span>; } </span><span>public</span> <span>function</span><span> actionView() { </span><span>echo</span> 'Hello View'<span>; } }</span>
訪問?r=site/view的時候,是不是看到輸出'Hello View'了呢?肯定是的,雖然我讀的書少,但是你騙不了我的,有圖有真相:
我一點也不喜歡用site這個名字,test才是我的最愛,於是我又建了一個test控制器來嘗試。
眼尖的一定看到怎麼寫了一個actions,這是什麼鬼?我也是剛試了才知道,它其實是另一種表示方式。
我記得在blog那個例子中有用過,用來顯示驗證碼:
<span>/*</span><span>* * Declares class-based actions. </span><span>*/</span> <span>public</span> <span>function</span><span> actions() { </span><span>return</span> <span>array</span><span>( </span><span>//</span><span> captcha action renders the CAPTCHA image displayed on the contact page</span> 'captcha'=><span>array</span><span>( </span>'class'=>'CCaptchaAction', 'backColor'=>0xFFFFFF,<span> )</span>, <span>//</span><span> page action renders "static" pages stored under 'protected/views/site/pages' // They can be accessed via: index.php?r=site/page&view=FileName</span> 'page'=><span>array</span><span>( </span>'class'=>'CViewAction',<span> )</span>,<span> ); }</span>
我把它理解為集中聲明第三方業務的動作集合,因為本控制器內的動作,我覺得還是action+ID 的方式直接。
什麼鬼?你說我用的是index.php/site/captcha 而不是index.php?r=site/captcha .這又得從設定檔說起。
'urlManager'=><span>array</span><span>( </span>'urlFormat'=>'path', 'rules'=><span>array</span><span>( </span>'post/<id:\d+>/<title:.*?>'=>'post/view', 'posts/<tag:.*?>'=>'post/index', '<controller:\w+>/<action:\w+>'=>'<controller>/<action>',<span> )</span>,<span> )</span>,
urlFormat 有path 和 get兩種,如果在main.php中沒有指定,那麼就是get方式,也就是index.php?r=site/captcha這種。如果指定了,即index.php/site/captcha這種
從字面上也很好理解,path就是像路徑的格式,get就是?這種形式。
關於路由和控制器部分的內容還有很多,但是本節就到這裡了。
以上就介紹了YII 的源碼分析(三),包括了方面的內容,希望對PHP教程有興趣的朋友有所幫助。

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

index.html代表網頁的首頁文件,是網站的預設頁面。當使用者造訪一個網站時,通常會先載入index.html頁面。 HTML(HypertextMarkupLanguage)是一種用來建立網頁的標記語言,index.html也是一種HTML檔。它包含網頁的結構和內容,以及用於格式化和佈局的標籤和元素。下面是一個範例的index.html程式碼:<

許多用戶在選擇智慧型手錶的時候都會選擇的華為的品牌,其中華為GT3pro和GT4都是非常熱門的選擇,不少用戶都很好奇華為GT3pro和GT4有什麼區別,下面就給大家介紹一下二者。華為GT3pro和GT4有什麼差別一、外觀GT4:46mm和41mm,材質是玻璃鏡板+不鏽鋼機身+高分纖維後殼。 GT3pro:46.6mm和42.9mm,材質是藍寶石玻璃鏡+鈦金屬機身/陶瓷機身+陶瓷後殼二、健康GT4:採用最新的華為Truseen5.5+演算法,結果會更加的精準。 GT3pro:多了ECG心電圖和血管及安

C語言return的用法有:1、對於傳回值類型為void的函數,可以使用return語句來提前結束函數的執行;2、對於傳回值型別不為void的函數,return語句的作用是將函數的執行結果傳回給呼叫者;3、提前結束函數的執行,在函數內部,我們可以使用return語句來提前結束函數的執行,即使函數並沒有回傳值。

為什麼截圖工具在Windows11上不起作用了解問題的根本原因有助於找到正確的解決方案。以下是截圖工具可能無法正常工作的主要原因:對焦助手已開啟:這可以防止截圖工具開啟。應用程式損壞:如果截圖工具在啟動時崩潰,則可能已損壞。過時的圖形驅動程式:不相容的驅動程式可能會幹擾截圖工具。來自其他應用程式的干擾:其他正在運行的應用程式可能與截圖工具衝突。憑證已過期:升級過程中的錯誤可能會導致此issu簡單的解決方案這些適合大多數用戶,不需要任何特殊的技術知識。 1.更新視窗與Microsoft應用程式商店應用程

原始碼:publicclassReturnFinallyDemo{publicstaticvoidmain(String[]args){System.out.println(case1());}publicstaticintcase1(){intx;try{x=1;returnx;}finally{x=3;}}#輸出上述程式碼的輸出可以簡單地得出結論:return在finally之前執行,我們來看下字節碼層面上發生了什麼事情。下面截取case1方法的部分字節碼,並且對照源碼,將每個指令的含義註釋在

第1部分:初始故障排除步驟檢查蘋果的系統狀態:在深入研究複雜的解決方案之前,讓我們先從基礎知識開始。問題可能不在於您的設備;蘋果的伺服器可能會關閉。造訪Apple的系統狀態頁面,查看AppStore是否正常運作。如果有問題,您所能做的就是等待Apple修復它。檢查您的網路連接:確保您擁有穩定的網路連接,因為「無法連接到AppStore」問題有時可歸因於連接不良。嘗試在Wi-Fi和行動數據之間切換或重置網路設定(「常規」>「重置」>「重置網路設定」>設定)。更新您的iOS版本:

php提交表单通过后,弹出的对话框怎样在当前页弹出php提交表单通过后,弹出的对话框怎样在当前页弹出而不是在空白页弹出?想实现这样的效果:而不是空白页弹出:------解决方案--------------------如果你的验证用PHP在后端,那么就用Ajax;仅供参考:HTML code

Vue3.2setup語法糖是在單文件組件(SFC)中使用組合式API的編譯時語法糖解決Vue3.0中setup需要繁瑣將聲明的變量、函數以及import引入的內容通過return向外暴露,才能在使用的問題1.在使用中無需return宣告的變數、函數以及import引入的內容,即可在使用語法糖//import引入的內容import{getToday}from'./utils'//變數constmsg='Hello !'//函數func
