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 相关文章推荐
IIS下配置Php+Mysql+zend的图文教程
Dec 08 PHP
提高PHP编程效率 引入缓存机制提升性能
Feb 15 PHP
PHP得到mssql的存储过程的输出参数功能实现
Nov 23 PHP
php将url地址转化为完整的a标签链接代码(php为url地址添加a标签)
Jan 17 PHP
PHP实现手机号码中间四位用星号(*)隐藏的自定义函数分享
Sep 27 PHP
php使用curl简单抓取远程url的方法
Mar 13 PHP
php常量详细解析
Oct 27 PHP
简介WordPress中用于获取首页和站点链接的PHP函数
Dec 17 PHP
简要剖析PHP的Yii框架的组件化机制的基本知识
Mar 17 PHP
ThinkPHP 模板substr的截取字符串函数详解
Jan 09 PHP
php检测mysql表是否存在的方法小结
Jul 20 PHP
php高性能日志系统 seaslog 的安装与使用方法分析
Feb 29 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
PHP.MVC的模板标签系统(三)
2006/09/05 PHP
yii实现CheckBox复选框在同一行显示的方法
2014/12/03 PHP
typecho插件编写教程(三):保存配置
2015/05/28 PHP
PHP随手笔记整理之PHP脚本和JAVA连接mysql数据库
2015/11/25 PHP
Kindeditor编辑器添加图片上传水印功能(php代码)
2017/08/03 PHP
jQuery UI 应用不同Theme的办法
2010/09/12 Javascript
jquery表单验证使用插件formValidator
2012/11/10 Javascript
JS子父窗口互相操作取值赋值的方法介绍
2013/05/11 Javascript
jQuery 选择器详解
2015/01/19 Javascript
JS利用cookie记忆当前位置的防刷新导航效果
2015/10/15 Javascript
jquery ezUI 双击行记录弹窗查看明细的实现方法
2016/06/01 Javascript
AngularJS入门教程之控制器详解
2016/07/27 Javascript
chrome下判断点击input上标签还是其余标签的实现方法
2016/09/18 Javascript
js最简单的双向绑定实例讲解
2018/01/02 Javascript
快速解决vue-cli不能初始化webpack模板的问题
2018/03/20 Javascript
vue中mint-ui的使用方法
2018/04/04 Javascript
详解vue组件基础
2018/05/04 Javascript
vue使用axios上传文件(FormData)的方法
2019/04/14 Javascript
javascript 模块依赖管理的本质深入详解
2020/04/30 Javascript
[47:45]Liquid vs OG 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
[42:23]完美世界DOTA2联赛PWL S3 Forest vs Rebirth 第二场 12.10
2020/12/13 DOTA
Python学习笔记之图片人脸检测识别实例教程
2019/03/06 Python
使用Python实现毫秒级抢单功能
2019/06/06 Python
PyQt5 加载图片和文本文件的实例
2019/06/14 Python
浅谈Python中函数的定义及其调用方法
2019/07/19 Python
python之生产者消费者模型实现详解
2019/07/27 Python
Flask项目中实现短信验证码和邮箱验证码功能
2019/12/05 Python
Django自定义全局403、404、500错误页面的示例代码
2020/03/08 Python
印度领先的在线时尚商店:Koovs
2016/08/28 全球购物
Redbubble法国:由独立艺术家设计的独特产品
2019/01/08 全球购物
英国自行车商店:AW Cycles
2021/02/24 全球购物
如何用Lucene索引数据库
2016/02/23 面试题
大学生旅游业创业计划书
2014/01/29 职场文书
群众路线剖析材料
2014/02/02 职场文书
自主招生教师推荐信
2014/05/10 职场文书
党的群众路线教育实践活动查摆问题自查报告
2014/10/10 职场文书