YII 的源码分析(3)
YII 的源码分析(三)
前面已经看完了启动一个yii程序所要经过的流程,以及渲染一个页面是怎么完成的。今天要分析的是yii是如何处理用户请求的。也就是控制和动作部分。
还是以helloworld为例演示这一过程。我们在地址栏输入http://localhost/study/yii/demos/helloworld/index.php,页面就显示了hello world.
前面的分析都是用的默认值,但是如果url有参数的时候,yii又是怎么处理的呢?带着这个问题,我们具体来分析一下。
在CWebApplication中有这样一行代码:
<span style="color: #800080;">$route</span>=<span style="color: #800080;">$this</span>->getUrlManager()->parseUrl(<span style="color: #800080;">$this</span>->getRequest());
这就是传说中的路由了,是不是有点小鸡冻呢?先看看getUrlManager是个神马。
<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> getUrlManager() { </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$this</span>->getComponent('urlManager'<span style="color: #000000;">); }</span>
这个又要通过找关系了.
<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> getComponent(<span style="color: #800080;">$id</span>,<span style="color: #800080;">$createIfNull</span>=<span style="color: #0000ff;">true</span><span style="color: #000000;">) { </span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$this</span>->_components[<span style="color: #800080;">$id</span><span style="color: #000000;">])) </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$this</span>->_components[<span style="color: #800080;">$id</span><span style="color: #000000;">]; </span><span style="color: #0000ff;">elseif</span>(<span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$this</span>->_componentConfig[<span style="color: #800080;">$id</span>]) && <span style="color: #800080;">$createIfNull</span><span style="color: #000000;">) { </span><span style="color: #800080;">$config</span>=<span style="color: #800080;">$this</span>->_componentConfig[<span style="color: #800080;">$id</span><span style="color: #000000;">]; </span><span style="color: #0000ff;">if</span>(!<span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$config</span>['enabled']) || <span style="color: #800080;">$config</span>['enabled'<span style="color: #000000;">]) { Yii</span>::trace("Loading \"<span style="color: #800080;">$id</span>\" application component",'system.CModule'<span style="color: #000000;">); </span><span style="color: #0000ff;">unset</span>(<span style="color: #800080;">$config</span>['enabled'<span style="color: #000000;">]); </span><span style="color: #800080;">$component</span>=Yii::createComponent(<span style="color: #800080;">$config</span><span style="color: #000000;">); </span><span style="color: #800080;">$component</span>-><span style="color: #000000;">init(); </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$this</span>->_components[<span style="color: #800080;">$id</span>]=<span style="color: #800080;">$component</span><span style="color: #000000;">; } } }</span>
执行了return $this->_components[$id]; id就是传进去的urlManager,其实从这里也还看不出什么,直接找到urlManager这个类,看parseUrl:
<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> parseUrl(<span style="color: #800080;">$request</span><span style="color: #000000;">) { </span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$this</span>->getUrlFormat()===self::<span style="color: #000000;">PATH_FORMAT) { </span><span style="color: #800080;">$rawPathInfo</span>=<span style="color: #800080;">$request</span>-><span style="color: #000000;">getPathInfo(); </span><span style="color: #800080;">$pathInfo</span>=<span style="color: #800080;">$this</span>->removeUrlSuffix(<span style="color: #800080;">$rawPathInfo</span>,<span style="color: #800080;">$this</span>-><span style="color: #000000;">urlSuffix); </span><span style="color: #0000ff;">foreach</span>(<span style="color: #800080;">$this</span>->_rules <span style="color: #0000ff;">as</span> <span style="color: #800080;">$i</span>=><span style="color: #800080;">$rule</span><span style="color: #000000;">) { </span><span style="color: #0000ff;">if</span>(<span style="color: #008080;">is_array</span>(<span style="color: #800080;">$rule</span><span style="color: #000000;">)) </span><span style="color: #800080;">$this</span>->_rules[<span style="color: #800080;">$i</span>]=<span style="color: #800080;">$rule</span>=Yii::createComponent(<span style="color: #800080;">$rule</span><span style="color: #000000;">); </span><span style="color: #0000ff;">if</span>((<span style="color: #800080;">$r</span>=<span style="color: #800080;">$rule</span>->parseUrl(<span style="color: #800080;">$this</span>,<span style="color: #800080;">$request</span>,<span style="color: #800080;">$pathInfo</span>,<span style="color: #800080;">$rawPathInfo</span>))!==<span style="color: #0000ff;">false</span><span style="color: #000000;">) </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$_GET</span>[<span style="color: #800080;">$this</span>->routeVar]) ? <span style="color: #800080;">$_GET</span>[<span style="color: #800080;">$this</span>->routeVar] : <span style="color: #800080;">$r</span><span style="color: #000000;">; } </span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$this</span>-><span style="color: #000000;">useStrictParsing) </span><span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> CHttpException(404,Yii::t('yii','Unable to resolve the request "{route}".', <span style="color: #0000ff;">array</span>('{route}'=><span style="color: #800080;">$pathInfo</span><span style="color: #000000;">))); </span><span style="color: #0000ff;">else</span> <span style="color: #0000ff;">return</span> <span style="color: #800080;">$pathInfo</span><span style="color: #000000;">; } </span><span style="color: #0000ff;">elseif</span>(<span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$_GET</span>[<span style="color: #800080;">$this</span>-><span style="color: #000000;">routeVar])) </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$_GET</span>[<span style="color: #800080;">$this</span>-><span style="color: #000000;">routeVar]; </span><span style="color: #0000ff;">elseif</span>(<span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$_POST</span>[<span style="color: #800080;">$this</span>-><span style="color: #000000;">routeVar])) </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$_POST</span>[<span style="color: #800080;">$this</span>-><span style="color: #000000;">routeVar]; </span><span style="color: #0000ff;">else</span> <span style="color: #0000ff;">return</span> ''<span style="color: #000000;">; }</span>
从上面的代码来看,如果我们不在url上传点东西,直接就return ''了。于是问题来了,参数要怎么传呢?
isset($_GET[$this-><span>routeVar]) <br><br></span>
<span style="color: #0000ff;">public</span> <span style="color: #800080;">$routeVar</span>='r';
于是有办法了,让我们一起来使点坏吧。加上这样的一个参数helloworld/index.php?r=abc
发现报错了。说明abc这个控制器是不存在的,事实上也是不存在的,使点小坏坏而已,正所谓男人不坏,女人不爱。
改成helloworld/index.php?r=site就可以显示hello world了,这是什么鬼原理呢?原因很简单,因为定义了site控制器嘛。
<span style="color: #0000ff;">class</span> SiteController <span style="color: #0000ff;">extends</span><span style="color: #000000;"> CController{ </span><span style="color: #008000;">/*</span><span style="color: #008000;">* * Index action is the default action in a controller. </span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> actionIndex() { </span><span style="color: #0000ff;">echo</span> 'Hello World'<span style="color: #000000;">; }</span><span style="color: #000000;">}</span>
好吧,这个我没有意见,但是actionIndex又是神么鬼?在yii中,这称为动作。它捕获的是控制器后面的参数,如果我们输?r=site/index就是index,动作是用“/"进行分隔的,为了验正一下我说的不是骗女孩子的鬼话,我在site控制器里加一个动作给你看一下:
<span style="color: #0000ff;">class</span> SiteController <span style="color: #0000ff;">extends</span><span style="color: #000000;"> CController{ </span><span style="color: #008000;">/*</span><span style="color: #008000;">* * Index action is the default action in a controller. </span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> actionIndex() { </span><span style="color: #0000ff;">echo</span> 'Hello World'<span style="color: #000000;">; } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> actionView() { </span><span style="color: #0000ff;">echo</span> 'Hello View'<span style="color: #000000;">; }}</span>
访问?r=site/view的时候,是不是看到输出'Hello View'了呢?肯定是的,虽然我读的书少,但是你骗不了我的,有图有真相:
我一点儿也不喜欢用site这个名字,test才是我的最爱,于是我又建了一个test控制器来尝试一下。
眼尖的一定看到怎么写了一个actions,这是什么鬼?我也是刚试了才知道,它其实是另一种表示方式。
我记得在blog那个例子中有用过,用来显示验证码:
<span style="color: #008000;">/*</span><span style="color: #008000;">* * Declares class-based actions. </span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> actions() { </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">array</span><span style="color: #000000;">( </span><span style="color: #008000;">//</span><span style="color: #008000;"> captcha action renders the CAPTCHA image displayed on the contact page</span> 'captcha'=><span style="color: #0000ff;">array</span><span style="color: #000000;">( </span>'class'=>'CCaptchaAction', 'backColor'=>0xFFFFFF,<span style="color: #000000;"> )</span>, <span style="color: #008000;">//</span><span style="color: #008000;"> 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 style="color: #0000ff;">array</span><span style="color: #000000;">( </span>'class'=>'CViewAction',<span style="color: #000000;"> )</span>,<span style="color: #000000;"> ); }</span>
我把它理解为集中声明第三方业务的动作集合,因为本控制器内的动作,我觉得还是action+ID 的方式直接。
什么鬼?你说我用的是index.php/site/captcha 而不是index.php?r=site/captcha .这又得从配置文件说起。
'urlManager'=><span style="color: #0000ff;">array</span><span style="color: #000000;">( </span>'urlFormat'=>'path', 'rules'=><span style="color: #0000ff;">array</span><span style="color: #000000;">( </span>'post/<id:>/<.><.><controller:><action:><controller><action><span style="color: #000000;"></span><span style="color: #000000;"></span></action></controller></action:></controller:></.></.></id:>

熱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

這篇文章帶大家解讀vue原始碼,來介紹一下Vue2中為什麼可以使用 this 存取各種選項中的屬性,希望對大家有幫助!
