侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

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

框架(架构)  /  管理员 发布于 7年前   370

本文分析了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程序设计有所帮助。

您可能感兴趣的文章:

  • Zend Framework教程之路由功能Zend_Controller_Router详解
  • ThinkPHP、ZF2、Yaf、Laravel框架路由大比拼
  • Zend Framework分发器用法示例
  • Zend Framework动作控制器用法示例
  • Zend Framework处理Json数据方法详解
  • Zend Framework入门教程之Zend_Registry组件用法详解
  • Zend Framework入门教程之Zend_Config组件用法详解
  • Zend Framework实现自定义过滤器的方法
  • ZendFramework框架实现连接两个或多个数据库的方法
  • Zend Framework框架实现类似Google搜索分页效果
  • Zend Framework开发入门经典教程
  • Zend Framework路由器用法实例详解


  • 上一条:
    Zend Framework框架Smarty扩展实现方法
    下一条:
    Zend Framework实现留言本分页功能(附demo源码下载)
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • Filament v3.1版本发布(0个评论)
    • docker + gitea搭建一个git服务器流程步骤(0个评论)
    • websocket的三种架构方式使用优缺点浅析(0个评论)
    • ubuntu20.4系统中宿主机安装nginx服务,docker容器中安装php8.2实现运行laravel10框架网站(0个评论)
    • phpstudy_pro(小皮面板)中安装最新php8.2.9版本流程步骤(0个评论)
    • 近期文章
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2018-05
    • 2020-02
    • 2020-03
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-08
    • 2020-11
    • 2021-03
    • 2021-09
    • 2021-10
    • 2021-11
    • 2022-01
    • 2022-02
    • 2022-03
    • 2022-08
    • 2023-08
    • 2023-10
    • 2023-12
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客