【原创】Zend Framework 2框架之MVC

ZendFramework 2框架之MVCphp

做者:sys(360电商技术组)css

1.前言

Zend Framework 2zend官方推出的php开源框架,基于php5.3。他全然採用面向对象的代码实现,并利用了php5.3的一些新特性,比方命名空间。闭包等。因为是官方的推荐的,今天咱们就来学习学习Zend Framework 2,因为本人知识浅薄,也没有实际的用Zend Framework 2作项目开发的经验。有错误的地方还请你们指正,也但愿在后面的开发中能用用该框架,此篇文章权当抛砖引玉。设计模式


2.体会

相对于咱们现在用的QFrameZendFramework 2让我感受仍是至关复杂。可能QFrame咱们仅仅用一天的时间。就能全然了解里面的详细实现。但是Zend Framework 2看了几天仍是让我无所适从。数组

让我感受QFrame很是实在,很是落地,学习使用相对easy,而Zend Framework 2就有点复杂了。Zend Framework 2MVC主要採用了Service Locator和事件驱动的设计模式。他提倡不论什么类库,扩展等资源都统一被视为服务对象。由一个管理者进行管理,所有服务对象都需要注冊给管理者。微信

当应用程序需要某些资源的时候,都从管理者中获取资源。这样的方法的优势在于解除了服务调用者和服务提供者之间的耦合。闭包

Zend Framework 2中用了很是多设计模式,这一点,是本身需要提升的。在咱们实际业务开发中,用的模式比較少,但愿在这方面有所增强。mvc

另外一个,个人体会是,Zend Framework 2在编码规范和凝视方面作的比較好。这让我想起来了一篇文章,说谷歌为何严格运行代码规范,你们开可以看看:http://developer.51cto.com/art/201108/283275.htmapp

这里说说Zend Framework 2的环境搭建以及Zend Framework 2mvc的形式,主要是一些网上和本身的一些使用心得。框架


3.环境搭建

我是依照官方的教程搭建的。函数

1.    首先下载Zend Framework 2的框架。

从官方站点 http://framework.zendcom/downloads/latest就可以下载到最新的Zend Framework 2框架,我用的版本号是2.3.0。将下载的源代码放到文件夹 /home/q/php/ZendFramework 如下。而后改动php.ini加入一个include_path进去 Zend Framework 2_path ="/home/q/php/ZendFramework/library"

2.    搭建开发模板环境。

也可以从官方下载演示样例模板开发环境。

官方提供了三种方法安装。网址:http://framework.zend.com/downloads/skeleton-app,第一种是用包的形式,另一种使用Git的形式。第三种是下载压缩包。我用的是最原始的方法,下载压缩包。下载完以后,你把它放到你喜欢的文件夹。


4.应用演示样例

好,现在来看一下咱们下载的一个演示样例模板

大概的文件夹结构就是这样的,入口是public/index.php文件。发现这个结构是否是似曾相识呢。对,和咱们现在使用的QFrame很是像。如下简介一下各个文件夹和文件的功能。

文件和文件夹结构

1.  /public文件夹

public文件夹是放cssjsimg等的一下资源文件。public/index.php是项目的入口文件,ngx配置的路径就是这个文件夹的路径。

public/index.php文件很是少

2/init_autoloader.php

        顾名思义,此文件是本身主动载入类用的。

3/config

        Config文件夹,是放配置用的。

这里,ZendFramework 2又细分了一下application.config.php 这个配置是应用程序级别的配置,是与整个项目有关的。比方需要载入哪些module的配置。

/config/autoload/文件夹下存放的是项目环境有关的配置信息。

4/vendor

        vendor文件夹通常存放第三方开发的或是本身开发的通用的模块

5/module

        

module文件夹通常存放当前项目的模块,每个Module就是一个全然独立的功能模块,可以拥有本身的配置文件、语言文件等等。

        /module/Application就是详细的一个module/module/Application/Module.php是此module的配置信息,每个新加的module必须有这个文件。/module/Application/config/module.config.php这里是对路由,控制器等的一些配置。/module/Application/src/里面主要是详细的控制器的实现,/module/Application/view里面主要是tpl文件。

        咱们在新加一个module的时候,文件夹结构也需要是类似的一个形式。


5.技术点解析

上面说到Zend Framework 2採用了Server Locator 和事件驱动的模式,这里咱们简介一下ServerLocator和事件驱动

1.  Server Locator

Zend Framework 2中用来实现Server Locator的是 Zend/ServiceManager/这个组件。

在Zend Framework 2中,不论什么的类库,扩展等资源都统一被视为服务对象,并在ServiceManager组件中注冊。当应用程序需要某个功能,好比Zend\Log 时,推荐的作法是在ServiceManager中获取。而不是像传统方式那样,include类文件以后再new一个对象出来。这样的方式的优势在于解除了服务调用者与服务提供者之间的耦合。做为使用者,不需要知道Zend\Log位置是在哪里,是怎样产生的。仅仅需要知道用Zend\ServiceManager::get()这样的方式来取得它便可了。

在这里,Zend Framework 2提供了4中注冊对象的方法

  • 初始化好的对象

调用setService方法,直接将建立好的对象注冊到管理器中

  • 延迟建立对象

调用setInvokableClass方法。事实上就是先注冊一个类的名字。当需要使用该服务对象时,ServiceManager实例化一个对象给你。

  • 工厂对象

调用setFactory方法。有不少服务对象的产生比較复杂,比方依据配置文件的内容来产生对象等。这时就需要有个专门的工厂来产生服务对象。工厂可以是匿名函数。也可以是实现了Zend\ServiceManager\FactoryInterface的类或对象。

  • 抽象工厂对象

假设要取得一个名字不存在的服务对象时。ServiceManager会去寻找注冊的抽象工厂,抽象工厂实现了Zend\ServiceManager\AbstractFactoryInterface,假设有某个抽象工厂的canCreateServiceWithName方法返回true,则 ServiceManager返回该抽象工厂的createServiceWithName方法所产生的对象。

        大体就是这样,这里也是ZendFramework 2为解耦合作的一些努力。

2.  事件驱动

Zend Framework 2初始化的时候,会依据配置注冊各种事件并绑定事件处理函数。主要是由Zend\EventManager组件来实现的事件驱动。主要有两个核心文件,Event.phpEventManager.php。一个是事件类(Event.php),一个是事件管理器类(EventManager.php)。这个里面也定义了很是多接口以及一些共享事件管理器等。

EventManager类主要负责绑定(attach)事件、解除(detach)事件、触发事件(trigger)。在EventManager类内部。维护着一个事件数组。事件数组维护着事件名称与事件处理函数的一对多的相应关系,也就是说一个事件名称可以绑定多个事件处理函数,当事件被触发后,依照绑定顺序,依次运行所绑定的事件处理函数。事件处理函数也被称为监听器(Listener)。在Zend Framework2中实现了一个优先队列,绑定事件的时候,可以给该事件也绑定上运行顺序,这样就能保证在一对多的关系中,你可以设置事件的运行顺序。

Zend Framework 2中预先定义了一些不一样的事件对象,如ModuleEventMvcEventViewEventSendResponseEvent等,他们都继承于 Zend\EventManager\Event。这些不一样的事件对象所起的做用事实上是同样的。都是在事件驱动的工做流程中把事件发生时的上下文信息传递给监听器(Listener),不一样之处在于事件发生时的逻辑环境。不论什么程序在逻辑上老是会有不一样的运行阶段的,在不一样阶段的上下文环境是不一样的。假设用一个事件对象来贯穿所有的运行阶段。一定会在该对象上附加所有阶段的上下文信息,从而致使该对象的臃肿,程序结构也不清晰。

所以这里的设计方法就是在不一样的逻辑环境中,使用不一样的事件对象。

Zend Framework 2在逻辑上把运行过程分红了两个部分,第一个部分是各模块和服务对象的初始化。第二部分是程序的运行。

首先咱们来看看/public/index.php 这个入口文件。

主要就三行代码,前面两行主要是autoload,第三行进入程序的运行

Zend\Mvc\Application::init(require'config/application.config.php')->run();

1.  初始化作了些什么

第一步,他产生了一个ServiceManager对象。

ServiceManager初始化的时候默认注冊了两个工厂。各自是事件管理器工厂(EventManagerFactory)和模块管理器工厂(ModuleManageFactory)是在Zend\Mvc\Service\ServiceManagerConfig中注冊的。

后面咱们会看到在另外一个类中注冊了更多的服务对象。事件管理器工厂比較简单。仅仅建立一个事件管理器(EventManager)对象。该对象负责整个MVC流程中所有事件的绑定以及触发。而模块管理器工厂比較复杂,在建立模块管理器(ModuleManager)对象时。还绑定了模块初始化过程当中的一些默认事件监听对象(Listener)

接下来是module的载入,

模块(Module)初始化过程当中。有四个事件(模块初始化事件)会被触发,依次是:

  • loadModules(開始载入所有模块)

  • loadModule.resolve(单个模块開始解析)

  • loadModule(单个模块開始载入)

  • loadModules.post(所有模块载入完毕)

以上这些事件定义在Zend\ModuleManager\ModuleEvent类中。在Zend Framework 2中,为这些事件绑定了不少默认的监听器(Listener)。大多数监听器的绑定由Zend\ModuleManager\Listener\DefaultListenerAggregate类完毕,它是一个默认监听器的聚合类。在loadModules的时候也绑定了很是多监听器。同一时候也默认注冊了很是多服务对象。

这样,当初始化阶段完毕后,会把所有模块(Module)文件夹下的ModuleConfig与全局的GlobConfig的内容合并成一个数组。GlobConfig会覆盖ModuleConfig下的同名内容。以Config为名字保存在ServiceLocator对象中,另外在ServiceLocator对象中另外一条为ApplicationConfig的内容,保存的是 config/application.config.php的内容。

2.程序运行

        当个模块初始化完毕以后。将进入程序的运行引导。如下这段就是进入程序的引导部分。

        在这里Zend Framework 2将绑定一系列的监听器,比方RouteListenerDispatchListenerSendResponseListenerViewManager

        RouteListener:为route事件绑定一个监听器。主要负责监听解析http请求中的url地址。

        DispatchListener:为dispatch事件绑定了一个监听器。主要是负责监听依据解析以后的url地址,找到相应的controller,而后运行相应的action

        SendResponseListener:为finish事件绑定了一个监听器。该监听器用来产生ResponseEvent对象,并在该对象上触发一系列与发送相应请求(Response)有关的事件。

        ViewManager:这个里面涉及到很是多东西,比方:变量的容器(Variables Containers)、视图模型(ViewModels)、视图助手(Helper)、模板(Template)、渲染策略(RenderStrategy)、脚本解析(Reslover)、响应策略(Response Strategy)等,在ViewManager中,为各种绑定了绑定了很是多模板处理相关监听器。

        绑定完毕以后,開始出发事件的引导事件:MvcEvent::EVENT_BOOTSTRAP。引导完以后就開始运行run()方法。run()方法主要就是触发了四个事件:MvcEvent::EVENT_ROUTEMvcEvent::EVENT_DISPATCH MvcEvent::EVENT_RENDERMvcEvent::EVENT_FINISH。绑定在这些事件上的监听器会负责完毕MVC的整个流程。


6.性能效率  

server 2U4G

如下是hello world程序,ZendFramework 2的程序流程图:

看上去很是复杂的样子。事实上原本就挺复杂(另存为可以放大看)。

精简一下,咱们再来看看初始化中耗时比較高的一些方法

        从上面的图,咱们发现大部分时间花在了mvc的初始化。

如下咱们来看看Zend Framework 2QPS

        看这个数据仍是挺慘的,QPS感受有点低。不能充当大任啊。


7.总结

Zend Framework 2在性能方面表现的太让人失望了。但是他的设计理念仍是挺好的,但是感受有点设计太重,初始化的时候作了太多的事情。载入了太多的模块。致使运行效率不高,在实际生产中仍是慎重使用。



-------------------------------------------------------------------------------------

黑夜路人,一个关注开源技术、乐于学习、喜欢分享的程序猿


博客:http://blog.csdn.net/heiyeshuwu

微博:http://weibo.com/heiyeluren

微信:heiyeluren2012  

想获取更多IT开源技术相关信息,欢迎关注微信!

微信二维码扫描高速关注本号码:


相关文章
相关标签/搜索