热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PEAR实践:PHP中典型结构MVC机制的实现

文章标题:PEAR实践:PHP中典型结构MVC机制的实现。Linux是中国IT实验室的一个技术频道。包含桌面应用,Linux系统管理,内核研究,嵌入式系统和开源等一些基本分类

  1.MVC概述
  1.1 什么是MVC
  MVC是MODEL_VIEW_CONTROL的缩写。MODEL_VIEW_CONTROL是软件设计的典型结构。在这种设计结构下,一个应用被分为三个部分:model,view和controller,每个部分负责不同的功能。model是指应用程序的数据,以及对这些数据的操作;view是指用户界面;controller负责用户界面和程序数据之间的同步,也就是完成两个方向的动作:一、在根据用户界面(view)的操作完成对程序数据(model)的更新,二、将程序数据(model)的改变及时反应到用户界面(view)上。
  
  1.2 MVC的优点
  
  使程序结构更加清晰,增强代码稳定性
  在MVC机制下,应用被清晰的分为model,view,controller三个部分,这三个部分分别依次对应了业务逻辑和数据、用户界面、用户请求处理和数据同步。我们知道,对于业务逻辑和数据、用户界面、用户请求处理和数据同步这三部分功能来讲,用户界面发生变动的可能性最大,控制部分变动次之,而业务逻辑是最稳定的。所以这种模块功能的划分有利于在代码修改过程中选取重点,而不是把具有不同功能的代码混杂在一起造成混乱。
  便于开发小组进行分工
  将应用划分为model,view,controller三个部分,还有利于在项目小组内按照小组成员各自的擅长进行分工,有利于三个部分并行开发、加快项目进度。
  
  2. MVC机制的实现
  2.1概述
  上一章介绍了MVC的一般概念,这一章将要讲述MVC机制在项目中的具体实现。
  
  2.1.1应用的技术
  MVC在某个特定应用上的实现是与该应用的具体技术密切相关的。在网站开发方面,JAVA是比较成熟和典型的,以一个EJB的项目为例,大部分的系统可能采用HTML技术,和J2EE(Java 2,Enterprise Edition)的相关技术,包括:HTML,JSP,JavaBean,Enterprise Java Bean,Servlet。这些技术分布于model,view,controller三个模块之中:view部分用到HTML、JSP和JavaBean技术;controller部分用到Servlet、Stateless Session Bean 、JavaBean 技术;model部分可能用到Entity Bean、Stateless Session Bean、JavaBean技术。
  
  但是,我们在这个项目用的是PHP技术来实现,因此,我们需要作出一些折衷。一方面,要尽量使程序的逻辑实现能够平滑地迁移到另一种技术实现(如J2EE),但同时,我们也要考虑到PHP这种脚本语言的局限性。PHP在对于面向对象的支持上同JAVA这种OO的语言不是同一档次,甚至比PERL都要差得很多。不过,幸运的是,我们的运气还不算太坏,因为PHP里面的PEAR是一个面向对象的扩展。使用PEAR的规范,我们一方面可以使用现有的一些PEAR模块,另一方面,可以使我们的程序是能够按照OO的思想来实现业务逻辑的。因此,我们将废弃过去那种模块化,过程化的编程方式,转变思路,将所有的东西都用类包装起来。
  
  在开始介绍实际的设计之前,我们不妨看看这个项目的需求情况
  
  2.1.2项目需求
  这个项目目的很简单,就是要做一个网站的发布系统。发布系统应该能够支持频道,子频道,栏目的划分,特权区的划分,用户角色划分,频道各种模板的定制,文章发布的流程控制……
  
  更为详细的这里就不再一一叙述了。
  
  2.1.3层次划分
  我们的应用不但可以按MVC机制分为model,view,controller三个层次,同时还应该可以按照实现的技术和逻辑关系划分为页面表现模块,业务控制模块,事务管理模块,工具模块4个模块;也可以按照具体的业务划分模块。下面再介绍一下这两种划分方式:
  
  按业务模块划分
  按实际业务分为用户管理、文章发布、模板维护、前台显示,系统管理五个部分。每一个部分都对应着发布系统的一个方面。这样,model、view、controller的实现组件就分布于五个业务模块之中。
  按实现技术划分
  由于我们的实现技术采用了HTML技术和PHP的相关技术,按照这些技术,我们又把整个应用分为页面表现层,业务控制层,事务管理层, 工具模块。这样MVC的3层结构又细化为上面这4个逻辑层(参见下图)
   
  2.1.4 典型的一个用户请求的时序图:
  如果你现在仍然对于我所说的这些划分感到很空洞和抽象的话,下面我们来看一个序列图,这个图展示了在MVC下面,一个request是如何响应和实现从数据的操作到页面显示的全过程:
   
  下面分别将分为具体介绍每一个模块的实现方式和在整个应用中的作用
  
  2.2页面表现层
  这部分的实现是最为简单的。由模板和使模板实例化的render类来完成。
  
  模板是使用纯HTML来编写,不存在任何的PHP代码和控制逻辑,确切地说,本层不涉及任何商业逻辑,它的用途就是根据选择的模板,和提供的实例的数据,生成一个完整的HTML页面
  
  下图是表现层的一个时序图示意:
  
  首先是AsisstantObj,这是Asisstant类的一个实例(关于Asisstant,后面我们会详细讨论),AsistantObj在init方法中,会分析表现层所要用到的2个xml配置文件,template.xml和render.xml,将相应的template 和render信息装载到系统中,并且会保存起来,在整个session中都可以使用。
  其次,由HanlderObj,hanlder类的一个实例,调用Asisstant类的lookupRender来找到某个模板对应的render实例
  调用render实例的setTemplate和setRenderData方法,前者是载入并初始化对应的模板文件,后者是设置需要实例化的实际数据
  调用render实例的Show方法。在render实例的show方法中,它会调用自身的一个renderIt方法(这个方法在render类里面是一个虚方法,每一个继承render的类都要实现自己的renderIt方法,这个方法里的主要工作就是根据renderdata生成模板的一个实例,具体实现形式参见下面的模板机制),之后,再调用renderObj的show方法将实例化后的页面显示再屏幕上面。
  
  2.2.1模板机制
  我们使用PEAR中的IT和ITX模块作为我们的模板引擎,之所以使用它,是因为ITX类是纯PEAR类,在功能上和PHPLIB中的TEMPLATE类似,但是使用上要简单一些。而且ITX有些特性特别适合这种模板的定制,考虑到我们的页面表现没有太特殊的地方,使用ITX能够满足我们的需求。
  
  关于ITX的具体使用细节,可以参考ITX的源代码,这里是它的一个简单的使用方法说明:
  
  new IntegratedTemplateExtention($root = "")
  构建函数,$root是装载模板文件的目录。注意,这里可能有个BUG,在使用下面的函数装载模板文件的时候,如果装载的文件名中带有路径的话,总是无法找到那个文件,所以我建议你设置$root为模板的目录,然后再使用下面的函数装载模板。
  loadTemplatefile($filename, $removeUnknownVariables = true, $removeEmptyBlocks = true)
  从指定的文件中加载模板,$removeUnknownVariables表示是否去掉未使用的变量标识,$removeEmptyBlocks表示是否去掉没有使用的块。
  setRoot($root)
  设置模板的目录
  setTemplate($template, $removeUnknownVariables = true, $removeEmptyBlocks = true)
  从指定的字符串中加载模板。如果你打算把模板数据存放在数据库中(推荐),这个函数是很有用的。
  setCurrentBlock($blockname)
  设置当前要解析的块名
  setVariable($variable, $value = "")
  设置变量标识的值
  parseCurrentBlock()
  解析当前的块
  touchBlock($block)
  设置指定的块,使之即使没有使用,也在输出中显示
  parse($block = "__global__", $flag_recursion = false)
  解析指定的块
  getBlocklist()
  得到模板中的块的列表
  blockExists($blockname)
  判断模板中是否存在指定的块
  
  2.2.2 模板的定义
  由于使用了ITX,模板的定义方式很简单,使用 来定义一个需要实例化的HTML块,使用{varname}来定义需要实例化的变量就可以了。对于循环,我们无需在页面上表现,而是放在render类里控制,我们通过选定一个HTML块,然后反复实例化这个块,就可以生成循环的HTML代码了。下面是一个例子:
  
  
  {name}{age}{sex}
  
     $obj->setCurrentBlock('LIST');
   for($I=0;$I<3;$I++){
  $obj->setVariable('name','panfan');
  $obj->setVariable('sex','BOY');
  $obj->setVariable('age',$I);
  $obj->parseCurrentBlock();
   }
  ?>
  这将生成如下的HTML代码:
  panfan0BOY
  panfan1BOY
  panfan2BOY
  
  2.2.3 实例化模板
  如在上节所看到的,我们通过给render类设置不同的template和不同的实例化数据,将生成不同的页面。那么,如何将模板和它所对应的render联系起来呢?这是个好问题。为了把复杂的问题简单化,我们没有考虑使用一个通用的能够实例化全部的模板和数据的render,因为这样会造成这个render逻辑非常负责,而是采用许多render,每个render可以实例化一个或者几个相近的模板。每一个模板都有一个它相对应的render类的id,这些定义是我们预先定义好的。我们使用了一个xml文件来定义应用中用到的全部的模板。这个xml文件名叫:template.xml,它的基本结构是这样的:
  
  
 
推荐阅读
  • Spring Boot 中静态资源映射详解
    本文深入探讨了 Spring Boot 如何简化 Web 应用中的静态资源管理,包括默认的静态资源映射规则、WebJars 的使用以及静态首页的处理方法。通过本文,您将了解如何高效地管理和引用静态资源。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 本文将深入探讨PHP编程语言的基本概念,并解释PHP概念股的含义。通过详细解析,帮助读者理解PHP在Web开发和股票市场中的重要性。 ... [详细]
  • Startup 类配置服务和应用的请求管道。Startup类ASP.NETCore应用使用 Startup 类,按照约定命名为 Startup。 Startup 类:可选择性地包括 ... [详细]
  • PHP 过滤器详解
    本文深入探讨了 PHP 中的过滤器机制,包括常见的 $_SERVER 变量、filter_has_var() 函数、filter_id() 函数、filter_input() 函数及其数组形式、filter_list() 函数以及 filter_var() 和其数组形式。同时,详细介绍了各种过滤器的用途和用法。 ... [详细]
  • 解决FCKeditor应用主题后上传问题及优化配置
    本文介绍了在Freetextbox收费后选择FCKeditor作为替代方案时遇到的上传问题及其解决方案。通过调整配置文件和调试工具,最终解决了上传失败的问题,并对相关配置进行了优化。 ... [详细]
  • C#设计模式学习笔记:观察者模式解析
    本文将探讨观察者模式的基本概念、应用场景及其在C#中的实现方法。通过借鉴《Head First Design Patterns》和维基百科等资源,详细介绍该模式的工作原理,并提供具体代码示例。 ... [详细]
  • PHP 编程疑难解析与知识点汇总
    本文详细解答了 PHP 编程中的常见问题,并提供了丰富的代码示例和解决方案,帮助开发者更好地理解和应用 PHP 知识。 ... [详细]
  • 本文介绍如何解决在 IIS 环境下 PHP 页面无法找到的问题。主要步骤包括配置 Internet 信息服务管理器中的 ISAPI 扩展和 Active Server Pages 设置,确保 PHP 脚本能够正常运行。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • CSS 布局:液态三栏混合宽度布局
    本文介绍了如何使用 CSS 实现液态的三栏布局,其中各栏具有不同的宽度设置。通过调整容器和内容区域的属性,可以实现灵活且响应式的网页设计。 ... [详细]
  • 本文介绍了如何利用JavaScript或jQuery来判断网页中的文本框是否处于焦点状态,以及如何检测鼠标是否悬停在指定的HTML元素上。 ... [详细]
  • 本文详细介绍了如何使用PHP检测AJAX请求,通过分析预定义服务器变量来判断请求是否来自XMLHttpRequest。此方法简单实用,适用于各种Web开发场景。 ... [详细]
  • 本文介绍了如何使用jQuery根据元素的类型(如复选框)和标签名(如段落)来获取DOM对象。这有助于更高效地操作网页中的特定元素。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
author-avatar
超人不会飞
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有