首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

Zend Framework 路由機制核心代碼深度解析

     編輯:PHP 綜合知識

本文從源碼層面分析 Zend Framework 路由機制:Apache mod_rewrite → 前端控制器分發 → 路由器逆序匹配 → 參數注入請求物件的完整鏈路,並深度解讀 Zend_Controller_Router_Route 構造與匹配算法。

一、路由調用鏈路

  1. Apache mod_rewrite 將請求導向 index.php。
  2. Zend_Controller_Front::dispatch() 分發請求。
  3. Zend_Controller_Router_Rewrite::route() 按加入順序逆序(後進先出)遍歷路由規則,調用 match() 匹配。
  4. 匹配成功:設置 $_currentRoute,解析參數注入 Zend_Controller_Request_Http。
  5. 無匹配:回退至 IndexController::indexAction()。

二、Route 構造函數解析

public function __construct($route, $defaults=array(), $reqs=array()) {
    $route = trim($route, $this->_urlDelimiter);
    $this->_defaults = (array)$defaults;
    $this->_requirements = (array)$reqs;
    if ($route != '') {
        foreach (explode($this->_urlDelimiter, $route) as $pos=>$part) {
            if (substr($part,0,1) == $this->_urlVariable) { // 變量
                $name = substr($part,1);
                $regex = isset($reqs[$name]) ? $reqs[$name] : $this->_defaultRegex;
                $this->_parts[$pos] = array('name'=>$name, 'regex'=>$regex);
                $this->_vars[] = $name;
            } else { // 靜態字符串
                $this->_parts[$pos] = array('regex'=>$part);
                if ($part != '*') $this->_staticCount++;
            }
        }
    }
}

核心屬性:_parts(規則分段)、_vars(變量名列表)、_staticCount(靜態段計數)。

三、匹配算法詳解

public function match($path) {
    $path = trim($path, $this->_urlDelimiter);
    $unique = array_combine(array_keys($this->_defaults), array_fill(0, count($this->_defaults), true));
    if ($path != '') {
        $path = explode($this->_urlDelimiter, $path);
        foreach ($path as $pos=>$pathPart) {
            if (!isset($this->_parts[$pos])) return false; // 路徑段超出規則
            if ($this->_parts[$pos]['regex'] == '*') { // 通配符
                $this->_getWildcardData(array_slice($path,$pos), $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;
                $pathStaticCount++;
            } elseif ($part['regex'] === null) { // 無正則變量
                if (strlen($pathPart) == 0) return false;
            } else { // 有正則變量
                $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;
            }
        }
    }
    // 合併:路徑解析值 + 通配符值 + 默認值(後者不覆蓋前者)
    $return = $this->_values + $this->_params + $this->_defaults;
    // 靜態段全部匹配
    if ($this->_staticCount != $pathStaticCount) 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 常見數據庫操作技巧匯總》。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved