前面已經看完了啟動一個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:>/<.><.><controller:><action:><controller><action><span></span><span></span></action></controller></action:></controller:></.></.></id:>

使用數據庫存儲會話的主要優勢包括持久性、可擴展性和安全性。 1.持久性:即使服務器重啟,會話數據也能保持不變。 2.可擴展性:適用於分佈式系統,確保會話數據在多服務器間同步。 3.安全性:數據庫提供加密存儲,保護敏感信息。

在PHP中實現自定義會話處理可以通過實現SessionHandlerInterface接口來完成。具體步驟包括:1)創建實現SessionHandlerInterface的類,如CustomSessionHandler;2)重寫接口中的方法(如open,close,read,write,destroy,gc)來定義會話數據的生命週期和存儲方式;3)在PHP腳本中註冊自定義會話處理器並啟動會話。這樣可以將數據存儲在MySQL、Redis等介質中,提升性能、安全性和可擴展性。

SessionID是網絡應用程序中用來跟踪用戶會話狀態的機制。 1.它是一個隨機生成的字符串,用於在用戶與服務器之間的多次交互中保持用戶的身份信息。 2.服務器生成並通過cookie或URL參數發送給客戶端,幫助在用戶的多次請求中識別和關聯這些請求。 3.生成通常使用隨機算法保證唯一性和不可預測性。 4.在實際開發中,可以使用內存數據庫如Redis來存儲session數據,提升性能和安全性。

在無狀態環境如API中管理會話可以通過使用JWT或cookies來實現。 1.JWT適合無狀態和可擴展性,但大數據時體積大。 2.Cookies更傳統且易實現,但需謹慎配置以確保安全性。

要保護應用免受與會話相關的XSS攻擊,需採取以下措施:1.設置HttpOnly和Secure標誌保護會話cookie。 2.對所有用戶輸入進行輸出編碼。 3.實施內容安全策略(CSP)限制腳本來源。通過這些策略,可以有效防護會話相關的XSS攻擊,確保用戶數據安全。

优化PHP会话性能的方法包括:1.延迟会话启动,2.使用数据库存储会话,3.压缩会话数据,4.管理会话生命周期,5.实现会话共享。这些策略能显著提升应用在高并发环境下的效率。

theSession.gc_maxlifetimesettinginphpdeterminesthelifespanofsessiondata,setInSeconds.1)它'sconfiguredinphp.iniorviaini_set().2)abalanceisesneededeededeedeedeededto toavoidperformance andunununununexpectedLogOgouts.3)

在PHP中,可以使用session_name()函數配置會話名稱。具體步驟如下:1.使用session_name()函數設置會話名稱,例如session_name("my_session")。 2.在設置會話名稱後,調用session_start()啟動會話。配置會話名稱可以避免多應用間的會話數據衝突,並增強安全性,但需注意會話名稱的唯一性、安全性、長度和設置時機。


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

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

熱門文章

熱工具

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

Atom編輯器mac版下載
最受歡迎的的開源編輯器

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