Zend Framework框架路由機(jī)制代碼分析
本文分析了Zend Framework框架路由機(jī)制代碼。分享給大家供大家參考,具體如下:
在框架中,有關(guān)路由的調(diào)用關(guān)系為:
1、apache的mod_rewrite模塊把請(qǐng)求路由到框架的啟動(dòng)腳本,一般是index.php;
2、前端控制器Zend_Controller_Front通過(guò)dispatch函數(shù)進(jìn)行請(qǐng)求分發(fā);
3、路由器Zend_Controller_Router_Rewrite通過(guò)route函數(shù)處理路由,對(duì)路由器中已有的路由規(guī)則,按照加入順序的逆序(類(lèi)似于棧,后進(jìn)先出)對(duì)每個(gè)route調(diào)用match函數(shù),以檢查請(qǐng)求是否和當(dāng)前路由規(guī)則匹配,如果匹配的話(huà)把路由器的當(dāng)前路由這個(gè)變量($_currentRoute)設(shè)置為匹配的路由,并把route解析出來(lái)的參數(shù)傳給Zend_Controller_Request_Http對(duì)象,到這里完成路由設(shè)置。
如果沒(méi)有發(fā)現(xiàn)路由,框架會(huì)使用Index控制器的index這個(gè)action。
對(duì)Zend_Controller_Router_Route中的函數(shù)代碼分析:
1、構(gòu)造函數(shù)
public function __construct($route, $defaults = array(), $reqs = array()) { $route = trim($route, $this->_urlDelimiter); //去掉規(guī)則首尾的url分隔符(默認(rèn)是/) $this->_defaults = (array) $defaults; //默認(rèn)值數(shù)組,以變量名為鍵 $this->_requirements = (array) $reqs; //變量需要滿(mǎn)足的正則表達(dá)式,以變量名為鍵 if ($route != '') { foreach (explode($this->_urlDelimiter, $route) as $pos => $part) { //把規(guī)則切分為一個(gè)數(shù)組 if (substr($part, 0, 1) == $this->_urlVariable) {//如果是一個(gè)變量的定義 $name = substr($part, 1); //獲取變量名 //如果該變量定義了對(duì)應(yīng)的正則表達(dá)式,則獲取該表達(dá)式,否則置為null $regex = (isset($reqs[$name]) ? $reqs[$name] : $this->_defaultRegex); //_parts數(shù)組包含了規(guī)則的各個(gè)部分,如果是變量的話(huà),數(shù)組中有name元素 $this->_parts[$pos] = array('name' => $name, 'regex' => $regex); //_vars包含了該規(guī)則中的所有變量的名字 $this->_vars[] = $name; } else { //普通字符串 $this->_parts[$pos] = array('regex' => $part); if ($part != '*') { $this->_staticCount++; //該規(guī)則的普通字符串的個(gè)數(shù) } } } } }
2、匹配算法
public function match($path) { $pathStaticCount = 0; $defaults = $this->_defaults; //默認(rèn)值數(shù)組,數(shù)組元素的鍵值是變量名 //默認(rèn)值數(shù)組的一個(gè)拷貝,不過(guò)變量的值全部換成布爾值,其實(shí)這個(gè)值并沒(méi)有實(shí)際用處,下面程序僅僅 //是通過(guò)判斷鍵值是否存在而確定是否包含一個(gè)變量,可能這么做是為了節(jié)省空間,不過(guò)要是這樣的話(huà) //不如直接使用 $this->_defaults了? if (count($defaults)) { $unique = array_combine(array_keys($defaults), array_fill(0, count($defaults), true)); } else { $unique = array(); } $path = trim($path, $this->_urlDelimiter); //傳入的path是已經(jīng)去掉baseUrl的,這里確保去掉首尾的分隔符 if ($path != '') { $path = explode($this->_urlDelimiter, $path); foreach ($path as $pos => $pathPart) { if (!isset($this->_parts[$pos])) { //把path根據(jù)url分隔符分割為數(shù)組后,把每一部分和規(guī)則的對(duì)應(yīng)部分比較,如果path中存在, //而規(guī)則中不存在對(duì)應(yīng)部分,那么該規(guī)則肯定不匹配,這里要注意$pos,是通過(guò)它把規(guī)則 //和path的對(duì)應(yīng)部分對(duì)應(yīng)起來(lái)。 return false; } if ($this->_parts[$pos]['regex'] == '*') { //如果規(guī)則的當(dāng)前部分是通配符*,則把path的剩余部分解釋為url傳遞過(guò)來(lái)的變量,他們按照 //“變量名/變量值”這樣的形式成對(duì)出現(xiàn) $parts = array_slice($path, $pos); //獲取path的剩余部分 $this->_getWildcardData($parts, $unique); break; } $part = $this->_parts[$pos]; $name = isset($part['name']) ? $part['name'] : null; $pathPart = urldecode($pathPart);//對(duì)傳過(guò)來(lái)的值進(jìn)行解碼 if ($name === null) {//普通字符串,和規(guī)則的對(duì)應(yīng)部分比較是否相等即可 if ($part['regex'] != $pathPart) { return false; } } elseif ($part['regex'] === null) { //如果是變量,但是沒(méi)有需要滿(mǎn)足的正則表達(dá)式,那么只有值不為空就可以了 if (strlen($pathPart) == 0) { return false; } } else {//如果對(duì)該變量需要滿(mǎn)足一個(gè)正則表達(dá)式,那么這里進(jìn)行驗(yàn)證 $regex = $this->_regexDelimiter . '^' . $part['regex'] . '$' . $this->_regexDelimiter . 'iu'; if (!preg_match($regex, $pathPart)) { return false; } } if ($name !== null) { // 如果是一個(gè)變量,則設(shè)置變量的值 $this->_values[$name] = $pathPart; $unique[$name] = true; //其實(shí)沒(méi)有必要設(shè)置,這個(gè)版本根本就沒(méi)有用它 } else { //把普通字符串的匹配計(jì)數(shù)加1,因?yàn)橐?guī)則中的普通字符串是必須在path中存在的,否則就是 //匹配失敗 $pathStaticCount++; } } } //$this->_values中保存的是分析獲取的變量,如果規(guī)則中存在‘*',則$this->_params是獲取的 //變量,否則是空數(shù)組,$this->_defaults是規(guī)則提供的默認(rèn)變量值,這里用‘+'把三個(gè)數(shù)組相加 //這樣的好處是如果后面的數(shù)組與前面的數(shù)組有相同的非整數(shù)的鍵值,后面的不會(huì)覆蓋前面的,這 //與array_merge函數(shù)有區(qū)別,后者是會(huì)覆蓋的。也就是說(shuō),如果$this->_values 中已經(jīng)有鍵controller //,那么$this->_defaults中的controller元素就被忽略,這樣就$this->_defaults中的默認(rèn)值只有在path //中不存在的時(shí)候才會(huì)出現(xiàn)在返回值中。 $return = $this->_values + $this->_params + $this->_defaults; // Check if all static mappings have been met if ($this->_staticCount != $pathStaticCount) {//規(guī)則的所有普通字符串必須在path中得到匹配 return false; } // 解析完后,規(guī)則定義的所有變量也必須全部出現(xiàn),否則視為不匹配 foreach ($this->_vars as $var) { if (!array_key_exists($var, $return)) { return false; } } return $return; }
更多關(guān)于zend相關(guān)內(nèi)容感興趣的讀者可查看本站專(zhuān)題:《Zend FrameWork框架入門(mén)教程》、《php優(yōu)秀開(kāi)發(fā)框架總結(jié)》、《Yii框架入門(mén)及常用技巧總結(jié)》、《ThinkPHP入門(mén)教程》、《php面向?qū)ο蟪绦蛟O(shè)計(jì)入門(mén)教程》、《php+mysql數(shù)據(jù)庫(kù)操作入門(mén)教程》及《php常見(jiàn)數(shù)據(jù)庫(kù)操作技巧匯總》
希望本文所述對(duì)大家基于Zend Framework框架的PHP程序設(shè)計(jì)有所幫助。
- Zend Framework教程之路由功能Zend_Controller_Router詳解
- ThinkPHP、Zend?Framework2、Yaf、Laravel框架路由大比拼
- Zend Framework分發(fā)器用法示例
- Zend Framework動(dòng)作控制器用法示例
- Zend Framework處理Json數(shù)據(jù)方法詳解
- Zend Framework入門(mén)教程之Zend_Registry組件用法詳解
- Zend Framework入門(mén)教程之Zend_Config組件用法詳解
- Zend Framework實(shí)現(xiàn)自定義過(guò)濾器的方法
- ZendFramework框架實(shí)現(xiàn)連接兩個(gè)或多個(gè)數(shù)據(jù)庫(kù)的方法
- Zend Framework框架實(shí)現(xiàn)類(lèi)似Google搜索分頁(yè)效果
- Zend Framework開(kāi)發(fā)入門(mén)經(jīng)典教程
- Zend Framework路由器用法實(shí)例詳解
相關(guān)文章
php使用event擴(kuò)展的io復(fù)用測(cè)試的示例
這篇文章主要介紹了php使用event擴(kuò)展的io復(fù)用測(cè)試的示例,幫助大家更好的理解和使用php,感興趣的朋友可以了解下2020-10-10PHP仿博客園 個(gè)人博客(1) 數(shù)據(jù)庫(kù)與界面設(shè)計(jì)
自學(xué)PHP大半年多了,斷斷續(xù)續(xù)地,但是最終還是堅(jiān)定了我的想法,將PHP繼續(xù)下去,所以寫(xiě)這個(gè)PHP的博客是為了找個(gè)穩(wěn)定的 PHP工作,不求工資多高,但求一收留之地2013-07-07PHP實(shí)現(xiàn)遠(yuǎn)程下載文件到本地
經(jīng)常寫(xiě)采集器發(fā)布接口需要使用到遠(yuǎn)程附件的功能,所以自己寫(xiě)了一個(gè)PHP遠(yuǎn)程下載文件到本地的函數(shù),一般情況下已經(jīng)夠用了,如果服務(wù)器支持CURL函數(shù),程序則會(huì)優(yōu)先選擇CURL,有需要的小伙伴可以參考下。2015-05-05用 Composer構(gòu)建自己的 PHP 框架之設(shè)計(jì) MVC
幾乎所有人都是通過(guò)學(xué)習(xí)某個(gè)框架來(lái)了解 MVC 的,這樣可能框架用的很熟,一旦離了框架一個(gè)簡(jiǎn)單的頁(yè)面都寫(xiě)不了,更不要說(shuō)自己設(shè)計(jì) MVC 架構(gòu)了,其實(shí)這里面也沒(méi)有那么多門(mén)道,原理非常清晰2014-10-10WordPress中設(shè)置Post Type自定義文章類(lèi)型的實(shí)例教程
這篇文章主要介紹了WordPress中設(shè)置Post Type自定義文章類(lèi)型的實(shí)例教程,后臺(tái)文章類(lèi)型的設(shè)置是WordPress的一大特色,然而自帶的文章類(lèi)型往往并不夠用,需要的朋友可以參考下2016-05-05php解析非標(biāo)準(zhǔn)json、非規(guī)范json的方式實(shí)例
這篇文章主要給大家介紹了關(guān)于利用php解析非標(biāo)準(zhǔn)json、非規(guī)范json的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12