Zend的MVC机制使用分析(一)


Posted in PHP onMay 02, 2013

代码

$front = Zend_Controller_Front::getInstance(); 
Zend_Layout::startMvc(array('layoutPath' => USVN_LAYOUTS_DIR)); $front->setRequest(new USVN_Controller_Request_Http()); 
$front->throwExceptions(true); 
$front->setBaseUrl($config->url->base); 
$router = new Zend_Controller_Router_Rewrite(); 
$routes_config = new USVN_Config_Ini(USVN_ROUTES_CONFIG_FILE, USVN_CONFIG_SECTION); 
$router->addConfig($routes_config, 'routes'); 
$front->setRouter($router); 
$front->setControllerDirectory(USVN_CONTROLLERS_DIR); 
Zend_Controller_Front::getInstance()->dispatch();

分析首先看下Zend_Controller_Front::getInstance是调用单例模式,实例化了它的内部属性_plugins,实例化了一个Zend_Controller_Plugin_Broker类。

这个类是管理front的插件的类。先看一个Front中的方法public function registerPlugin(Zend_Controller_Plugin_Abstract $plugin, $stackIndex = null)

意思是如果你有一个自己的插件要插入使用的话,调用这个函数能把你自己的插件委托给Zend_Controller_Plugin_Broker使用。

如果你有愿望继续跟下去你会看到注册插件做的一件最根本的事情就是把request和response放入到你的插件中去(setRequest和setResponse)。

class Zend_Controller_Plugin_Broker extends Zend_Controller_Plugin_Abstract

这个实现了抽象类Zend_Controller_Plugin_Abstract。
Zend_Controller_Plugin_Abstract是所有插件的抽象类,所有用户自己定义的插件或者Zend已有的插件都要从这个类继承。这里就看到了,前端控制器Front就是使用broker作为用户插件注册。

这个抽象类可以被实现的函数有:
Zend的MVC机制使用分析(一)

routeStartup: 在路由发送请求前被调用

routeShutdown:在路由完成请求后被调用

dispatchLoopStartup:在进入分发循环(dispatch loop)前被调用

Predispatch:在动作由分发器分发前被调用

postdispatch:在动作由路由器分发后被调用

dispatchLoopShutdown:在进入分发循环(dispatch loop)后被调用

 

我们还看到了getRequest, getResponse两个方法,我们可以通过他们分别从控制器中获取request对象和response对象

 

好了,扯远了,回到最开始的代码,Zend_Controller_Front::getInstance实际上来看做的事情就是注册了一个broker插件放到$front中。

 

下面一行代码

Zend_Layout::startMvc(array('layoutPath' => USVN_LAYOUTS_DIR));

看到Zend/Layout.php中,startMvc做了两件事:首先是调用自己的构造函数来实例化自己(切记带着initMvc参数为true),然后是设置参数。

Zend_Layout的构造函数比较复杂,就跟到里面看看。首先也是设置传递进来的参数$options,我们这个例子中是传递进来Array ( [layoutPath] => /var/www/html/usvn/app/layouts )这个array作为options,构造函数就是调用$this->setOptions($options);

这个setOptions做的事是根据array的每个key,调用$this->set$key($val);也就是说,以上面的例子来说,setOptions调用了setLayoutPath("/var/www/html/usvn/app/layouts")

顺藤摸瓜,setLayoutPath的功能是设置自己类的this->_layout为"/var/www/html/usvn/app/layouts", 然后设置_enable为true;这两个属性记住,以后会有使用的。

 

回退到Zend_Layout的构造函数,初始化options之后是调用了_initVarContainer();

这个函数做了这么个事情:

$this->_container = Zend_View_Helper_Placeholder_Registry::getRegistry()->getContainer(__CLASS__);

又出现了Zend_View_Helper_Placeholder_Registry(我翻译为:Zend视图助手注册表)

 

getRegistry() 将Zend_View_Helper_Placeholder_Registry作为key,Zend_View_Helper_Placeholder_Registry类的实例作为value注册到之前见过的Zend_Registry中。这个类的构造函数就什么事都没有。

 

getRegistry()返回了Zend_View_Helper_Placeholder_Registry实例,下面调用getContainer(__CLASS__)。 这里的__CLASS__是什么,当前调用的类,自然就是Zend_Layout了。这里是getContainer("Zend_Layout")

 

进入到getContainer里面,它调用了createContainer("Zend_Layout")。createContainer("Zend_Layout")是在Registry中以Zend_Layout为key,Zend_View_Helper_Placeholder_Container类为value的array。

 

Zend_View_Helper_Placeholder_Container实现抽象类Zend_View_Helper_Placeholder_Container_Abstract,这个抽象类实际上也是一个ArrayObject,这个在之前的文章有提到过了,是一个和泛型类一样的东东。

 

好了,这里不跟下去了,回头到Zend_Layout的构造函数

_initVarContainer结束了,下面是调用两个重要的函数:

$this->_setMvcEnabled(true);

$this->_initMvc();

Mvc大家一定很熟悉,我们来看看这里是怎么个MVC的

setMvcEnabled没什么特别,设置标志位this->_mvcEnabled

_initMvc做了两件事,_initPlugin和_initHelper。

先看initPlugin:

获取PluginClass,这里的pluginClass就是Zend_Layout_Controller_Plugin_Layout,可以看到,这里是作为一个插件的形式放进来的。

接着又获取了Zend_Controller_Front的实例,调用:

$front->registerPlugin(

new $pluginClass($this),

99

);

 

记得前面对Zend_Controller_Front的分析不?里面有registerPlugin的函数,是将插件委托给front的broker来用。有人就会问后面的99是什么意思?是插件的索引顺序,越后面的插件越后执行插件的动作。

 

下面再看_initHelper:

获取helperClass,这里的helperClass就是Zend_Layout_Controller_Action_Helper_Layout

if (!Zend_Controller_Action_HelperBroker::hasHelper('layout')) {

。。。

Zend_Controller_Action_HelperBroker::getStack()->offsetSet(-90, new $helperClass($this));

}

如果Action_HelperBroker没有layout的helper的话

就执行下面的offsetSet命令。将-90和Zend_Layout_Controller_Action_Helper_Layout实例作为参数传入。

和plugin同样的关系,将Zend_Layout_Controller_Action_Helper_Layout实例作为value存入到this->_helpersByPriority和this->_helpersByNameRef去了

前面的-90是权重,也是要保证这个helper是最后调用(看最后一行是krsort排序)

好了,Layout的构造函数就这样分析结束了。

PHP 相关文章推荐
一个目录遍历函数
Oct 09 PHP
php仿ZOL分页类代码
Oct 02 PHP
IIS php环境配置PHP5 MySQL5 ZendOptimizer phpmyadmin安装与配置
Nov 18 PHP
php图片处理:加水印、缩略图的实现(自定义函数:watermark、thumbnail)
Dec 02 PHP
获取php页面执行时间,数据库读写次数,函数调用次数等(THINKphp)
Jun 03 PHP
destoon调用企业会员公司形象图片的实现方法
Aug 21 PHP
php比较相似字符串的方法
Jun 05 PHP
简单的php+mysql聊天室实现方法(附源码)
Jan 05 PHP
基于命令行执行带参数的php脚本并取得参数的方法
Jan 25 PHP
Yii使用smsto短信接口的函数demo示例
Jul 13 PHP
PHP入门教程之面向对象基本概念实例分析
Sep 11 PHP
ThinkPHP5+Layui实现图片上传加预览功能
Aug 17 PHP
基于Zend的Captcha机制的应用
May 02 #PHP
PHP静态调用非静态方法的应用分析
May 02 #PHP
Mysql中分页查询的两个解决方法比较
May 02 #PHP
记录mysql性能查询过程的使用方法
May 02 #PHP
基于MySQL分区性能的详细介绍
May 02 #PHP
php中使用$_REQUEST需要注意的一个问题
May 02 #PHP
PHP执行批量mysql语句的解决方法
May 02 #PHP
You might like
一个很方便的 XML 类!!原创的噢
2006/10/09 PHP
php is_file 判断给定文件名是否为一个正常的文件
2010/05/10 PHP
深入PHP运行环境配置的详解
2013/06/04 PHP
php采用curl访问域名返回405 method not allowed提示的解决方法
2014/06/26 PHP
微信公众号开发之微信公共平台消息回复类实例
2014/11/14 PHP
php读取本地json文件的实例
2018/03/07 PHP
php设计模式之享元模式分析【星际争霸游戏案例】
2020/03/23 PHP
最短的IE判断var ie=!-[1,]分析
2014/05/28 Javascript
js实现仿Discuz文本框弹出层效果
2015/08/13 Javascript
jQuery实现ajax的叠加和停止(终止ajax请求)
2016/08/08 Javascript
JS实现Ajax的方法分析
2016/12/20 Javascript
JS实现移动端按首字母检索城市列表附源码下载
2017/07/05 Javascript
微信小程序wx:for和wx:for-item的用法详解
2018/04/01 Javascript
Vue2.0 实现歌手列表滚动及右侧快速入口功能
2018/08/08 Javascript
mpvue+vuex搭建小程序详细教程(完整步骤)
2018/09/30 Javascript
JavaScript setInterval()与setTimeout()计时器
2019/12/27 Javascript
15个简单的JS编码标准让你的代码更整洁(小结)
2020/07/16 Javascript
如何基于viewport vm适配移动端页面
2020/11/13 Javascript
基于jQuery拖拽事件的封装
2020/11/29 jQuery
举例讲解Python中的list列表数据结构用法
2016/03/12 Python
Python3+django2.0+apache2+ubuntu14部署网站上线的方法
2018/07/07 Python
python查找指定文件夹下所有文件并按修改时间倒序排列的方法
2018/10/21 Python
pytorch 在sequential中使用view来reshape的例子
2019/08/20 Python
在Python中获取操作系统的进程信息
2019/08/27 Python
python元组的概念知识点
2019/11/19 Python
基于Python实现视频的人脸融合功能
2020/06/12 Python
Python 下载Bing壁纸的示例
2020/09/29 Python
英国美术用品购物网站:Cass Art
2019/10/08 全球购物
关于毕业的广播稿
2014/01/10 职场文书
红领巾心向党广播稿
2014/01/19 职场文书
煤矿安全生产责任书
2014/04/15 职场文书
读书月活动方案
2014/05/22 职场文书
师范生免费教育协议书范本
2014/10/09 职场文书
三方协议书
2015/01/27 职场文书
MySQL数据库⾼可⽤HA实现小结
2022/01/22 MySQL
nginx中封禁ip和允许内网ip访问的实现示例
2022/03/17 Servers