搜尋
首頁php教程php手册Zend Framework框架路由机制代码分析

Zend Framework框架路由机制代码分析

Jun 06, 2016 pm 07:32 PM
frameworkzend程式碼分析機制框架路由

本文分析了Zend Framework框架路由机制代码。分享给大家供大家参考,具体如下: 在框架中,有关路由的调用关系为: 1、apache的mod_rewrite模块把请求路由到框架的启动脚本,一般是index.php; 2、前端控制器Zend_Controller_Front通过dispatch函数进行请求

本文分析了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; //变量需要满足的正则表达式,以变量名为键
  if ($route != '') {
   foreach (explode($this->_urlDelimiter, $route) as $pos => $part) {
    //把规则切分为一个数组
    if (substr($part, 0, 1) == $this->_urlVariable) {//如果是一个变量的定义
     $name = substr($part, 1); //获取变量名
     //如果该变量定义了对应的正则表达式,则获取该表达式,否则置为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) {
      //如果是变量,但是没有需要满足的正则表达式,那么只有值不为空就可以了
     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; //其实没有必要设置,这个版本根本就没有用它
    } 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程序设计有所帮助。

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

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

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用