Zend Framework架構路由機制程式碼分析,zendframework
本文分析了Zend Framework架構路由機制代碼。分享給大家供大家參考,具體如下:
在架構中,有關路由的調用關係為:
1、apache的mod_rewrite模組把請求路由到架構的啟動指令碼,一般是index.php;
2、前端控制器Zend_Controller_Front通過dispatch函數進行請求分發;
3、路由器Zend_Controller_Router_Rewrite通過route函數處理路由,對路由器中已有的路由規則,按照加入順序的逆序(類似於棧,後進先出)對每個route調用match函數,以檢查請求是否和當前路由規則匹配,如果匹配的話把路由器的當前路由這個變數($_currentRoute)設定為匹配的路由,並把route解析出來的參數傳給Zend_Controller_Request_Http對象,到這裡完成路由設定。
如果沒有發現路由,架構會使用Index控制器的index這個action。
對Zend_Controller_Router_Route中的函數程式碼分析:
1、建構函式
public function __construct($route, $defaults = array(), $reqs = array()){ $route = trim($route, $this->_urlDelimiter); //去掉規則首尾的url分隔字元(預設是/) $this->_defaults = (array) $defaults; //預設值數組,以變數名為鍵 $this->_requirements = (array) $reqs; //變數需要滿足的Regex,以變數名為鍵 if ($route != '') { foreach (explode($this->_urlDelimiter, $route) as $pos => $part) { //把規則切分為一個數組 if (substr($part, 0, 1) == $this->_urlVariable) {//如果是一個變數的定義 $name = substr($part, 1); //擷取變數名 //如果該變數定義了對應的Regex,則擷取該運算式,否則置為null $regex = (isset($reqs[$name]) ? $reqs[$name] : $this->_defaultRegex); //_parts數組包含了規則的各個部分,如果是變數的話,數組中有name元素 $this->_parts[$pos] = array('name' => $name, 'regex' => $regex); //_vars包含了該規則中的所有變數的名字 $this->_vars[] = $name; } else { //一般字元串 $this->_parts[$pos] = array('regex' => $part); if ($part != '*') { $this->_staticCount++; //該規則的一般字元串的個數 } } } }}
2、匹配演算法
public function match($path){ $pathStaticCount = 0; $defaults = $this->_defaults; //預設值數組,數組元素的索引值是變數名 //預設值數組的一個拷貝,不過變數的值全部換成布爾值,其實這個值並沒有實際用處,下面程式僅僅 //是通過判斷索引值是否存在而確定是否包含一個變數,可能這麼做是為了節省空間的,不過要是這樣的話 //不如直接使用 $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是已經去掉baseUrl的,這裡確保去掉首尾的分隔字元 if ($path != '') { $path = explode($this->_urlDelimiter, $path); foreach ($path as $pos => $pathPart) { if (!isset($this->_parts[$pos])) { //把path根據url分隔字元分割為數組後,把每一部分和規則的對應部分比較,如果path中存在, //而規則中不存在對應部分,那麼該規則肯定不匹配,這裡要注意$pos,是通過它把規則 //和path的對應部分對應起來。 return false; } if ($this->_parts[$pos]['regex'] == '*') { //如果規則的當前部分是萬用字元*,則把path的剩餘部分解釋為url傳遞過來的變數,他們按照 //“變數名/變數值”這樣的形式成對出現 $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);//對傳過來的值進行解碼 if ($name === null) {//一般字元串,和規則的對應部分比較是否相等即可 if ($part['regex'] != $pathPart) { return false; } } elseif ($part['regex'] === null) { //如果是變數,但是沒有需要滿足的Regex,那麼只有值不為空白就可以了 if (strlen($pathPart) == 0) { return false; } } else {//如果對該變數需要滿足一個Regex,那麼這裡進行驗證 $regex = $this->_regexDelimiter . '^' . $part['regex'] . '$' . $this->_regexDelimiter . 'iu'; if (!preg_match($regex, $pathPart)) { return false; } } if ($name !== null) { // 如果是一個變數,則設定變數的值 $this->_values[$name] = $pathPart; $unique[$name] = true; //其實沒有必要設定,這個版本根本就沒有用它 } else { //把一般字元串的匹配計數加1,因為規則中的一般字元串是必須在path中存在的,否則就是 //匹配失敗 $pathStaticCount++; } } } //$this->_values中儲存的是分析擷取的變數,如果規則中存在‘*',則$this->_params是擷取的 //變數,否則是空數組,$this->_defaults是規則提供的預設變數值,這裡用‘+'把三個數組相加 //這樣的好處是如果後面的數組與前面的數組有相同的非整數的索引值,後面的不會覆蓋前面的,這 //與array_merge函數有區別,後者是會覆蓋的。也就是說,如果$this->_values 中已經有鍵controller //,那麼$this->_defaults中的controller元素就被忽略,這樣就$this->_defaults中的預設值只有在path //中不存在的時候才會出現在傳回值中。 $return = $this->_values + $this->_params + $this->_defaults; // Check if all static mappings have been met if ($this->_staticCount != $pathStaticCount) {//規則的所有一般字元串必須在path中得到匹配 return false; } // 解析完後,規則定義的所有變數也必須全部出現,否則視為不匹配 foreach ($this->_vars as $var) { if (!array_key_exists($var, $return)) { return false; } } return $return;}
更多關於zend相關內容感興趣的讀者可查看本站專題:《Zend FrameWork架構入門教程》、《php優秀開發架構總結》、《Yii架構入門及常用技巧總結》、《ThinkPHP入門教程》、《php物件導向程式設計入門教程》、《php+mysql資料庫操作入門教程》及《php常見資料庫操作技巧匯總》
希望本文所述對大家基於Zend Framework架構的PHP程式設計有所協助。
您可能感興趣的文章:
- Zend Framework架構教程之Zend_Db_Table_Rowset用法執行個體分析
- Zend Framework教程之Zend_Db_Table_Row用法執行個體分析
- Zend Framework教程之Zend_Db_Table用法詳解
- Zend Framework教程之Zend_Form組件實現表單提交並顯示錯誤提示的方法
- Zend Framework開發入門經典教程
- Zend Framework架構Smarty擴充實現方法
- Zend Framework實現具有準系統的留言本(附demo源碼下載)
- Zend Framework實現將session儲存在memcache中的方法
- Zend Framework分頁類用法詳解
- Zend Framework實現多檔案上傳功能執行個體
- Zend Framework入門之環境配置及第一個Hello World樣本(附demo源碼下載)
- Zend Framework教程之串連資料庫並執行增刪查的方法(附demo源碼下載)
- Zend Framework教程之Zend_Db_Table表關聯執行個體詳解
http://www.bkjia.com/PHPjc/1113719.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/1113719.htmlTechArticleZend Framework架構路由機制程式碼分析,zendframework 本文分析了Zend Framework架構路由機制代碼。分享給大家供大家參考,具體如下: 在架構中,有...