4.17 Zend_Controller/Zend_View——在PHP中构筑MVC模式的应用程序
在Java等应用程序中广泛采用的MVC构架,随着PHP5中面向对象功能的加强,PHP5中也出现了支持MVC模式的程序包。Zend Framework就是其中的杰出代表。
Zend_Controller作为Zend Framework中包含的多个组件的中心组件,提供构筑MVC模式应用程序的基本框架。
因为下一章将详细介绍使用Zend Framework构筑实际应用程序的大型实例,作为先导,本节尝试生成一个非常简单的“Hello World”程序,先介绍一下Zend Framework中以Zend_Controller为中心的基本编程规则。
本例要点
MVC(Model-View-Controller)就是,将应用程序按照“Model(商业逻辑)”、“View(外观)”,“Controller(Model与View的控制)”三个效能划分成不同的子系统。在以前的例子中,“Model”、“View”、“Controller”都由同一个程序来承担的,从开发效率以及程序的维护性上来看,都是不可取的。
这时候,出现了上一节介绍的模板引擎。使用模板引擎后,可将外观(View)与商业逻辑(Model)分开开发。
但是,在进行大规模的系统的开发是,仅仅是将外观(View)与商业逻辑(Model)分开开发,还是远远不够的。为什么呢?从Web页面上以各种方式送出各种各样的数据,同时在复杂的大规模系统,画面的迁移也会非常复杂。
这些代码都放在Model中,最后Model代码又会变得很复杂,程序的可读性以及可维护性还是会显著地下降。通常可以想象的是,这样的Model代码中会还有很多“if else”的条件判断。
为了解决上述矛盾,在Model与View加入了一个称作Controller的层。Controller就是主要用来控制何时调用Model,处理输入输出数据,最后将结果显示在不同的View中。就像名字所显示的,Controller就是用于控制Model与View的。
MVC的关系图如图4-12所示。
图4-12 MVC的关系图
确实对于简单的程序来说,这样的分割可能显得特别没有必要。但是,对那些大规模的项目来说,做了这样的分割后,不仅可以提供开发效率,而且日后发生式样改变时,影响可以控制在相对小的范围以内。
今后在进行系统开发时,不仅要考虑满足用户的功能需求,而且也要考虑整个系统的开发效率,以及今后的可维护性。只有这样才能在竞争中立于不败之地。
刚开始对于框架编程,可能没有什么直观的感觉。Zend Framework是一个单纯的、轻量级的框架。这里首先从最基本的构架开始介绍它。
目录结构
*在光盘中的例子中,为了方便,将“/application”目录放在“/chap4/zend”目录下,实际应用时,请移动目录。
使用Zend_Controller时,首先需要做一些准备。这里就文件的配置、生成等方面,介绍一下几个基本的关键要点。
应用程序的目结构
本节例子中的目录结构,是利用Zend_Controller应用程序的典型结构。
要点就是,在公开目录(/htdocs目录)下只配置了配置文件.htaccess与前台控制台程序index.php(实际的应用中,还要加上.js、.css、.jpeg等文件),其他的应用程序文件放置在公开目录以外。
Zend_Controller就拥有这种能将终端用户能访问到的文件数目降低到最小,防止代码泄漏的特征。
另外,应用程序下的子目录是空的,本节例子中没有用到这些目录,但不表示这些目录没有用,这里就先记住有这些目录吧。
前台控制台(font controller)与Rewrite引擎
Zend_Controller采用了被称为前台控制台(font controller)的处理客户端请求的方式。
前几章所有应用程序都是传统的,由被请求的页面自己处理请求的方式。而前台控制台方式中,前台控制台会接受所有的请求,然后会根据不同的请求,调用相应的Action Controller。
Action Controller才是最终处理请求的程序。
另外,前台控制台根据请求分配Action Controller的方式,称为“路由(routing)”,而实际分配处理的过程被称“分配(dispatch)”。
前台控制台如图4-13所示。
图4-13 前台控制台
这样,首先将请求集中到一个地方,当需要追加认证或履历等共通功能时,可以通过前台控制台实现统一管理,提高了应用程序的可维护性。
支持前台控制台这种构架的是被称为“Rewrite引擎”的功能。Rewrite引擎的具体设定,后面会有介绍。由于有了这个Rewrite引擎,所有请求(这里都是以“http://localhost/samples/chap4/zend/”开始的请求)都由前台控制台来分配。
Action Controller的配置与命名规则
上面介绍过,Action Controller是由前台控制台调用的,担任处理各个固定请求的脚本。Action Controller中的文件名,控制类(Controller)名,方法(action)名都必须遵守表4-14所示的命名规则。
表4-14 命名规则
Action Controller被放置在应用程序目录下的./controller目录中。
Action Controller的名称与请求URI在处理调度上有紧密的联系。前台控制台解析请求了URI后,来决定需要调用哪个Action Controller。例如对于如下的URI:
Action名
Controller名就为index,action名也为index。这样将调用IndexController.php中定义的IndexController类的indexAction方法。用户自定义参数为处理中需要的参数,Zend_Controller中可以以这种扩展路径的形式指定。当然不需要时,可以省略掉。
另外,Controller名index,Action名index是默认的名称,可以省略的。
以上的URI都是同一个意义。但是请注意的是,只有当后续的路径没有时才能省略。像下述的路径省略方式就不可取。
到
View脚本的配置与命名规则
View脚本是,接受Action Controller的处理结果,并生成最终输出画面的脚本,放置在应用程序目录下的/views/scripts目录下。
但是View脚本文件也有对应于Controller名以及Action名的命名方式,请务必注意。例如与Controller为index,action为index对应的View脚本文件名为index/index.phtml(即在/views/scripts目录下,建目录index,再在index下生成index.phtml文件)。扩展名.phtml有点特殊,内容与PHP脚本相同。
本例代码
Apache提供的Rewrite引擎有效化。
1.RewriteEngine on
针对/samples/chap4/zend/目录下的所有请求都交给index.php(但是扩展名为.js、.ico、.gif、.jpg、.png、.css的文件除外)。想改变重定向目录时,修改第2行的/samples/chap4/zend/部分,想改变除外的扩展名时,修改第3行。
Zend_Controller_Front类提供前台控制台的基本功能。Zend_Controller_Front::getInstance方法生成Zend_Controller_Front对象。
指定Action Controller的放置目录,要改变放置目录,修改路径部分。
设定前台控制台的动作参数。noViewRenderer参数是自动rendering模式(View脚本自动调用功能)是否有效的设定。此处设置为FALSE(自动rendering模式有效)。
跳转到Action Controller。
Zend_Controller_Action类提供Action Controller的基本功能。定义Action Controller时必须继承Zend_Controller_Action类。
index/index动作(action)是最初调用的静态页面,因为不需要任何处理,所以是空壳函数。
index/post动作是“送信”按钮按下后的应答画面,将显示“hello XXX”的信息。
Zend_Controller中使用请求对象来取得请求信息。使用Zend_Controller_Action::getRequest方法取得Query信息的请求对象。取得Form信息的请求对象时使用getPost方法。
设定View变量result,view变量就是在View中能看到的变量。此处以$this->view->变量=值的形式设定。
从Action方法传过来的view变量,以“$this->变量名”的形式取得。这里使用的escape方法与htmlspecialchars函数相似,进行特殊代码转换。
补充
本例注意事项
本节中使用的Zend_Translate/Zend_Date组件,都是Zend Framework提供的组件,使用前必须事先设置为利用可能的状态。
按照第1章的步骤配置Zend Framework的代码的同时,在Windows环境中以下述的步骤使Rewrite引擎有效(Linux环境中配置Apache时,Rewrite引擎已经嵌入其中,不用特别的设置了)。
在初始状态下,在上述的设置开头有“#”,被引用起来了,请将“#”删除。如果没有上述设置,在LoadModule指令设置后加上上面的设置。
httpd.conf修改后,必须重新启动Apache。
Zend Framework的复制功能
Zend Framework的标准View功能由Zend_View组件提供。但是,Zend_View组件提供的是,与View相关的基本共通功能,没有提供与Smarty一样的特殊语法。
为了在View中显示参数值,还是必须在View脚本中插入像<?php ?>这样的程序块,很不方便。从分隔商业逻辑与显示画面这个角度上讲,显有点模糊(在View中会含有逻辑)。这正是问题的所在。
这里,在下一章,我们将使用Smarty(这样灵活的自由组合正是Zend Framework的优点)来处理View的显示部分。Zend Framework与Smarty的组合请参照下一章的介绍。
请求对象和应答对象
在Zend_Controller中管理客户端的输入输出的是请求对象和应答对象。在Action方法中可以分别通过getRequest/getReponse方法取得。请求对象/应答对象中可供使用的方法如表4-15所示。
表4-15 请求对象/应答对象中可供使用的方法
以前在取得请求信息中使用的超级变量($_GET/$_POST等)在Zend_Controller的程序中不推荐使用了。另外,在Zend Framework中处理Session时,不是请求对象,必须使用Zend_Session组件(第5章会有介绍)。
应答对象在渲染模式(rendering mode)有效的情况下不能使用,而且就是在渲染模式无效时,也尽量少用应答对象进行内容的输出,通常只用在进行与头(header)相关的操作中。在Zend_Controller中,内容的输出应该在View脚本(模板)中进行。
共有条评论 网友评论