admin 管理员组文章数量: 887021
2024年2月18日发(作者:delphi 列表控件)
零基础学 PHP第20章PHP与MVC开发模式MVC是一种源远流长的软件设计模式,早在20世纪70年代就已经出现了基于MVC的开发模式。随着Web应用开发的广泛展开,也因为Web应用需求复杂度的提高,MVC这一设计模式也渐渐被Web应用开发所采用。随着Web应用的快速增加,MVC模式对于Web应用的开发无疑是一种非常先进的设计思想,无论选择哪种语言,也无论应用多复杂,它都能为构造产品提供清晰的设计框架。MVC模式使得Web应用更加强壮,更加有弹性,也更加个性化。本章先介绍什么是MVC,然后介绍几款PHP中常见的基于MVC的开发框架及其应用。20.1 什么是MVC模型MVC模型是开发大型Web应用时可以采用的程序架构。MVC是Model_View_Control的缩写,简单地讲,Model即程序的数据或数据模型,View是程序视图界面,Control是程序的流程控制处理部分。Model_View_Control是软件设计的典型结构。如今这一设计思想也开始在Web开发中实践并流行起来。在这种设计结构下,一个应用被分为三个部分:model、view和controller,每个部分负责不同的功能。model是指应用程序的数据,以及对这些数据的操作,view是指用户界面,controller负责用户界面和程序数据之间的同步,也就是完成两个方向的动作。这个两个动作如下所示。❑根据用户界面(view)的操作完成对程序数据(model)的更新。❑将程序数据(model)的改变及时反应到用户界面(view)上。PHP中的MVC架构可以用图20.1来描述。使用MVC架构Web应用程序,可以使程序结构更加清晰,增强代码稳定性。在MVC机制下,应用图20.1 PHP的MVC架构数据库MySQL/SQLite数据抽象层数据模型(M)用户视图(V)这里就是控制器(C)业务逻辑被清晰地分为model、view、controller 3个部分,这3个部分依次对应了业务逻辑和数据、用户界面、用户请求处理和数据同步。这种模块功能的划分有利于在代码修改过程中选取重点,而不是把具有不同功能的代码混杂在一起造成混乱。随着开发规模的扩大,这种架构将有利于提高开发效率,有利于控制开发进度。励志照亮人生 编程改变命运378
第20章PHP与MVC开发模式20.2 MVC模型的组成MVC是一个设计模式,它使Web应用程序的输入、处理和输出分开进行。MVC Web应用程序被分成3个核心部件:数据模型(Model—M)、视图(View—V)、控制器(Controller—C)。一个好的MVC设计,不仅可以使模型、视图、控制器高效完成各自的任务处理,而且可以让它们完美地结合起来,完成整个Web应用。20.2.1 控制器控制器负责协调整个应用程序的运转,简单来讲,控制器的作用就是接受浏览器端的请求。它接受用户的输入并调用模型和视图去完成用户的需求,当用户单击Web页面中的超链接或发送HTML表单时,控制器本身不输出任何东西,它只是接收请求并决定调用哪个模型构件去处理浏览器端发出的请求,然后确定用哪个视图来显示模型处理返回的数据。20.2.2 数据模型通常,Web应用的业务流程处理过程对其他层来说是不可见的,也就是说,模型接受视图请求的数据,并返回最终的处理结果。数据模型的设计可以说是MVC最主要的核心。对一个开发者来说,需要专注于Web应用的业务模型的设计。MVC设计模式把应用的模型按一定的规则抽取出来,抽取的层次很重要,抽象与具体不能隔得太远,也不能太近。MVC并没有提供模型的设计方法,只是用来组织管理这些模型,以便模型的重构和提高重用性。从面向对象编程来讲,MVC定义了一个顶级类,在告诉它的子类有哪些是可以做的。这一点对开发人员非常重要。既然是数据模型,那么它就携带着数据,但数据模型又不仅仅是数据,它还负责执行那些操作这些数据的业务规则。通常会将业务规则的实现放进模型,这样保证Web应用的其他部分不会产生非法数据。这意味着,模型不仅仅是数据的容器,还是数据的监控者。20.2.3 视图从用户角度说,视图就是用户看到的HTML页面。从程序角度说,视图负责生成用户界面,通常根据数据模型中的数据转化成HTML输出给用户。视图可以允许用户以多种方式输入数据,但数据本身并不由视图来处理,视图只是用来显示数据。在实际应用中,可能会有多个视图访问同一个数据模型。如“用户”这一数据模型中,就有一个视图显示用户信息列表,还有管理员使用的用于查看、删除用户的视图。这两个视图同时访问“用户”这一数据模型。在很多Web开发中,都会使用模板来生成用户最终看到的HTML页面。关于模板的有关知识,将在下一节介绍。20.3 PHP开发中的模板技术在基于MVC模型的Web应用开发中,模板是不可或缺的。模板定义了一个并不完全的类HTML文件,它为用户视图提供了最基本内容的框架,一些重要的数据需要在程序中添加到模板中,从而形成完整的用户视图。本节将先介绍模板的基本概念和其在PHP程序中的用法,然后介绍一个优秀的模板励志照亮人生 编程改变命运379
零基础学 PHP引擎—Smarty。20.3.1 什么是模板对于什么是模板这个问题,可以这样解释:模板是一组插入了HTML的PHP脚本或者说是插入了PHP脚本的HTML,通过这种插入的内容来表示变化的数据。例如,下面的代码就是一个简单模板文件的例子。
第20章PHP与MVC开发模式的模板变量,如代码第12行所示。函数print_page()非常简单,只有一行代码,这行代码通过正则表达式替换函数将模板变量替换为程序中的实际数据。虽然这个在PHP程序中使用模板变量的示例程序很小,但却体现了模板在PHP程序中的处理思想。当然实际的模板引擎要比这个复杂得多,也更能满足实际需要。本章的下一小节将会介绍一个被PHP官方推荐使用的模板引擎,并通过一些实例讲解模板引擎的使用。图20.2 在PHP程序中使用模板20.3.3 Smarty模板引擎对PHP来说,有很多模板引擎可供选择,如最早的PHPLIB template和后起之秀Fast template,经过数次升级,已经相当成熟稳定。本小节要介绍的是一款易于使用且功能强大的PHP模板引擎—Smarty。它分开了逻辑程序和外在的内容,提供了一种Web页面易于管理的方法。Smarty显著特点之一是“模板编译”,这意味着Smarty读取模板文件然后用它们创建PHP脚本。这些脚本创建以后将被执行,而不是去解析模板文件的语法。可以通过Smarty的官方网站获取Smarty模板引擎,官方网站的网址是/。下面关于Smarty的介绍将以稳定的2.5版本为准。下载Smarty安装包,解压后有3个目录:libs模板文件目录,其下有4个类文件1个目录。首先介绍的是,它应该是整个Smarty模板的核心类。通常,需要在Web应用程序目录下建立如下所示的目录结构。❑appdir/smarty/libs,此目录对应压缩包下的libs目录,存放smarty需要的类文件。❑appdir/smarty/templates_c,此目录存放模板文件,程序用到的模板文件都放在这里。❑appdir/smarty/templates,存放模板属性文件。❑appdir/smarty/configs,存放相关配置文件。20.3.4 Smarty模板引擎的使用下面通过一个实例程序介绍Smarty模板引擎在PHP程序中的使用。首先定义一个简单模板文件,命名为,并保存在当前目录下的templates子目录下。tpl是Smarty模板文件使用的后缀名,该模板文件如代码20-2所示。代码20-2 一个简单的Smarty模板文件(){* 这里是Smarty模板的注释*}
零基础学 PHP先来解释一下这个模板文件。{*与*}之间的部分是模板页的注释,它在Smarty对模板进行解析时不进行任何处理,仅起说明作用。{$name}是模板变量,它是Smarty中的核心组成,采用左边界符{与右边界符}包含着、以PHP变量形式给出。接下来完成显示模板的PHP程序,如代码20-3所示。代码20-3 在PHP程序中使用Smarty模板引擎()template_dir = "./templates"; //设置模板目录$smarty->compile_dir = "./templates_c"; //设置编译目录$smarty->left_delimiter = "{"; //设定左右边界符为{}, Smarty推荐使用的是<{}>$smarty->right_delimiter = "}";$smarty->assign("name", "Smarty"); //进行模板变量替换$smarty->assign("page_title", "Smarty的使用"); //进行模板变量替换$smarty->display(""); //编译并显示位于./templates下的模板?>这段代码第2行将Smarty类心的类文件包含到当前文件中。代码第4行生成Smarty类的实例$smarty,它代表了一个Smarty模板。代码第5、6行分别设置模板文件所在目录及模板文件编译后存放目录。代码第8、9行设定了模板变量的界定符为“{”和“}”。第11、12行将模板变量替换为实际内容,最后在代码第14行显示最终用户看到HTML视图。代码20-3的执行结果如图20.3所示。如果转到当前目录下的子目录template_c,可以看到其中有一个由Smarty模板引擎生成的PHP文件,这个文件最终由Smarty
第20章PHP与MVC开发模式法,即使用echo结构输出Smarty模板引擎获取的实际变量。从这个文件的内容,读者应该看到一点Smarty模板引擎处理模板的机制。本节只是举了一个很简单的例子,告诉读者Smarty模板引擎的使用方法及其实现机理,有兴趣的读者还需要通过Smarty模板引擎的官方网站获取更多的如何应用Smarty模板引擎的知识,并在较大规模的实际应用中尝试使用Smarty模板引擎。20.4 常见的基于MVC的PHP开发框架简介PHP开发永远是一个活跃的领域,随着MVC设计方法、敏捷开发理念的流行,Web应用领域产生了大量的开发框架,使用这些框架可以迅速搭建Web应用,降低开发成本和缩小开发周期。PHP社区也出现了大量的MVC开发框架,本节介绍4种比较活跃的PHP开发框架:CodeIgniter、CakePHP、Zend Frame work和FleaPHP。这些框架都有各自的特点与不足,而且它们有各自的设计目标和设计理念,这决定了它们有其适应的范围。实际开发中,应该根据具体的需求和应用环境选择适合的开发框架。20.4.1 CodeIgniterCodeIgniter是一个小巧但功能强大的有PHP编写的基于MVC的Web应用开发框架,作为一个简单而不是强大的开发工具包,它可以为PHP程序员建立功能完善的Web应用程序。CodeIgniter的确是一个不错的MVC框架。这里还需要说明一点,CodeIgniter是经过Apache/BSD-style开源许可授权的免费框架。CodeIgniter使用了模型(Model)、视图(View)、控制器(Controller)的方法,最小化了模板中的程序代码量。CodeIgniter生成的URL非常干净而且是对搜索引擎友好的。不同于标准的“字符串查询”方法,CodeIgniter使用了基于段的(segment-based)URL表示法,如下所示。/aaa/bbb/123这样的地址非常有利于搜索引擎搜索。除此之外,CodeIgniter拥有全面的开发类库,可以完成大多数Web应用的开发任务。例如,读取数据库、发送电子邮件、数据确认、保存session、对图片的操作等。而且CodeIgniter提供了完善的扩展功能,可以有效帮助开发人员扩展更多的功能。更多的关于CodeIgniter框架的内容,可以访问其官方网站,网址是,从这里也可以下载最新版本和稳定版本的CodeIgniter。20.4.2 CakePHPCakePHP封装了数据库访问逻辑,对于小应用来说可以获得令人惊叹的开发效率。CakePHP比较有特色的地方是命令行代码生成工具让开发者可以快速生成应用程序框架。如果读者了解Ruby onRails,在使用CakePHP构建Web应用之后,会发现CakePHP几乎就是Rails在PHP上的翻版。CakePHP也是完全基于MVC架构的Web开发框架,它有以下一些特点。❑兼容PHP4和PHP5。❑数据库交互和简单查询的集成。❑MVC体系结构。❑自定义的URL的请求分配器(Request dispatcher)。383励志照亮人生 编程改变命运
零基础学 PHP❑内置验证机制。❑快速灵活的模板。❑支持AJAX。❑灵活的视图缓存。❑可在任何Web站点的子目录里工作,不需要改变Apache配置。❑命令行生成Web站点框架。CakePHP也有一些不足,就是Model实现的过于复杂,CakePHP中的Model不但尝试封装行数据集,甚至连数据库访问也包含在内。随着应用开发的展开,Model类的高度复杂性和几乎无法测试的特性,使得项目的重构变得困难重重,大大降低了开发效率和应用的可维护性。可以通过CakePHP的官方网站/了解关于这个框架更多的内容,从其官方网站上也可以下载最新版本和稳定版本的CakePHP。20.4.3 Zend FrameworkZend Framework是完全基于PHP语言的针对Web应用开发的框架,与众多的其他PHP开发框架相比,Zend Framework是一个PHP“官方的”的框架,它由Zend公司负责开发和维护。ZendFramework同样基于MVC模式,Zend Framework采用了ORM(Object Relational Mapping,对象关系映射)思路,这是一种为了解决面向对象编程与关系数据库存在的互不匹配现象的技术。简单地说,这种技术将数据库中的一个表映射为程序中的一个对象,表中的字段映射为对象的属性,然后通过提供的方法完成对数据库的操作。就这一点而言,Zend Framework很相似于现在流行的非PHP的开发框架Ruby on Rails。另外,上一小节介绍的CakePHP也实现了这种技术。Zend Framework的另一个特点是,它实现了Front Controller模式,也就是说,所有的HTTP请求都会转发到同一个入口,然后再有路由功能模块转到相应的Controller。Zend Framework和其他几款PHP开发框架相比,比较庞大。除了最基本的MVC模型以外,Zend Framework还提供了一系列高级功能,下面是这些功能的一部分。❑Zend_Acl实现了非常灵活的权限控制机制。❑Zend_Cache提供了一种通用的缓存方式,可以将任何数据缓存到文件系统、数据库、内存。❑Zend_Log提供通用的log解决方案,支持格式化的log信息。❑Zend_Json封装了数据在PHP和JSON格式之间的转换操作。❑Zend_Feed封装了对RSS和ATOM的操作。这里非常简单地介绍了Zend Framework,读者可以通过Zend Framework的官方网站/获取更多的信息,也可从官方网站获取最新版本的Zend Framework。20.4.4 FleaPHPFleaPHP一款优秀的国产Web开发框架,FleaPHP致力于减少开发者创建Web应用程序的工作量,并降低开发难度和强度,提高开发效率。FleaPHP除了MVC模式实现、分发调度器、模板引擎等常见功能外,还有以下一些重要特点。❑简单、容易理解的MVC模型❑易于使用、高度自动化的数据库操作❑尽可能少的配置励志照亮人生 编程改变命运384
第20章PHP与MVC开发模式❑自动化的数据验证和转义❑丰富的组件❑与Smarty模板集成提示可以通过FleaPHP的官方网站/获取完全的关于该框架的知识和内容,也可以从官方网站上下载最新版本和稳定版本的FleaPHP。正如该框架官方网站上所说的那样:FleaPHP缺乏Zend Framework那样巨大的号召力,也没有CakePHP和Symfony那样庞大的社区,但FleaPHP仍然是一个值得你花时间去了解、去学习的框架。最后,笔者在这里加一句,国产的基于MVC的Web开发框架FleaPHP值得开发人员支持和大力推广,值得在实际开发中使用。20.5 CodeIgniter框架应用从20.4节介绍的4个框架中,本书选择CodeIgniter作为讲解实例。通过前面的几小节内容,读者已经了解到CodeIgniter是一个为用PHP编写Web应用程序的人员提供的工具包。它的目标是实现比从零开始编写代码更快速的开发项目,为此,CodeIgniter提供了一套丰富的类库来满足通常的任务需求,并且提供了一个简单的接口和逻辑结构来调用这些库。CodeIgniter可以将需要完成的任务代码量最小化,这样开发人员就可以把更多的精力放到项目的开发上。另外,CodeIgniter提供了非常完善的文档,读者通过这些文档可以快速学习、理解CodeIgniter,并且可以在开发中高效使用CodeIgniter框架。20.5.1 CodeIgniter的技术特点CodeIgniter在设计之初就有其明确的目标,这个目标就是在最小化、最轻量级的开发包中得到最大的执行效率、功能和灵活性。为了这个目标,CodeIgniter在开发过程的每一步都致力于基准测试、重构和简化工作,拒绝加入任何不助于目标的东西。从技术和架构角度看,CodeIgniter 按照下列目标创建。❑动态实例化。在CodeIgniter中,组件的导入和函数的执行只有在被要求的时候才进行,而不是在全局范围。❑松耦合。耦合是指一个系统的组件之间的相关程度。组件互相依赖越少,那么系统的重用性和灵活性就越好。CodeIgniter的目标构建是一个非常松耦合的系统。❑组件单一性。单一是指组件有一个非常小的专注目标。在CodeIgniter中,为了达到最大的用途,最大的每个类和它的功能都是高度自治的。CodeIgniter是基于模型、视图、控制器这一设计模式的,从前面的学习中,读者了解到该模式将应用程序的逻辑层和表现层进行分离。在实践中,由于表现层从PHP脚本中分离了出来,所以它允许网页中只包含很少的PHP代码。在CodeIgniter中,模型代表数据结构,包含取出、插入、更新数据库的这些功能。视图通常是一个网页,但是在CodeIgniter中,一个视图也可以是一个页面片段,如头部、顶部HTML代码片段。它还可以是一个RSS页面,或其他任一页面。控制器相当于一个指挥者,或者说是一个“中介”,它负责联系视图和模型,以及其他任何处理HTTP请求和产生网页的资源。385励志照亮人生 编程改变命运
零基础学 PHP20.5.2 安装CodeIgniterCodeIgniter安装分为如下所示的4个步骤。1)解压缩安装包。2)把CodeIgniter文件夹和里面的文件部署到服务器,通常位于应用服务器的根目录。3)编辑application/config/文件,设置基本URL。4)如果需要使用数据库,编辑application/config/,在这个文件中设置数据库参数。下面介绍CodeIgniter框架的组织结构。从官方网站下载CodeIgniter框架,解压缩后可以看到最主要的一个目录是system,该目录就是CodeIgniter框架的目录。除此之外,还有一个文件,该文件用来做一些初始化配置,它还起到处理HTTP请求的作用。20.5.3 CodeIgniter的Controller(控制器)在CodeIgniter中,一个controller就是一个类文件,controller所属的类和普通的PHP类几乎没有区别,唯一有特点的是Controller类的命名方式,它所采用的命名方式可以使该类和URI关联起来。例如下面的URL地址就说明了这个问题。//news/当访问到上面这个地址时,CodeIgniter会尝试找一个名叫的控制器(controller),然后加载它。当一个controller的名字匹配URI段的第一部分,即news时,它就会被加载。代码20-4演示创建一个简单的Controller类。代码20-4 使用CodeIgniter的Controller ()把它保存在application/controllers/目录下,以本书为例,通过浏览器访问地址localhost/ch20//hello,可以看到如图20.4所示的执行结果。注意在CodeIgniter中,类名首字母必须大写。例如,下面的代码写法就是不正确的。励志照亮人生 编程改变命运386
第20章PHP与MVC开发模式代码20-4定义了一个Hello,它继承于Controller类,Controller类是CodeIgniter控制器基类,所有的控制器都将从这个类派生。这个例子中用到的方法名是index()。如果URI的第2部分为空,会默认载入index方法,也就是说,也可以将地址写成localhost/ch20//hello/index来访问。由此可知,URI的第2部分决定调用控制器中哪个方法,代码20-5演示了在Hello控制器中加入其他方法,此时的如下所示。图20.4 Controller的使用代码20-5 为Controller添加方法()此时通过地址localhost/ch20//hello/saylucky访问可以看到如图20.5所示的效果。如果URI超过两个部分,那么超过的部分将被作为参数传递给相关方法。如地址//products/shoes/sandals/123,URI中的sandals和123将被当作参数传递给products类的方法shoes。代码20-6演示了这种用法,仍然以为例,完整代码如下所示。图20.5 为Hello控制器添加方法代码20-6 向Controller的方法传递参数()
零基础学 PHP}function sayhello($name){echo "Hello, $name !";}}?>假设为方法sayhello()传递参数michael,通过地址localhost/ch20// hello/sayhello/michael访问,可以看到如图20.6所示的结果。图20.6 向方法传递参数20.5.4 CodeIgniter的Model(数据模型)在CodeIgniter中,Model是专门用来和数据库打交道的PHP类。通常在Model类里包含插入、更新、删除数据的方法。CodeIgniter中的Model类文件存放在application/models/目录,可以在里面建立子目录。最基本的Model定义如下面的代码所示。class Model_name extends Model{function Model_name(){parent::Model();}}其中Model_name是模型类的名字,类名的首字母必须大写,并且确保自定义的Model类继承了基本Model类。Model类的文件名应该是Model类名的小写版,如一个Model类的代码如下所示。class User extends Model{function User_model(){parent::Model();}}那么该Model类对应的文件名是application/models/。Model通过Controller载入,如下代码所示。$this->load->model('Model_name');励志照亮人生 编程改变命运388
第20章PHP与MVC开发模式其中Model_name是要载入的Model类的名字。模型载入后,就可以通过如下代码所示的方法使用它。$this->load->model('Model_name');$this->Model_name->function();20.5.5 CodeIgniter的View(视图)在CodeIgniter中,视图从不直接调用,必须被一个控制器来调用。1)使用文本编辑器创建一个名为的文件,如代码20-7所示。代码20-7 视图文件()
Hello everyone!
2)将该代码保存到application/views/目录下。然后,需要使用某个方法载入该视图文件。这个方法的用法如下所示。$this->load->view('name')3)这行代码中,name是需要载入的视图文件的名字,文件的后缀名没有必要写出。接下来,在hello控制器的文件中,写入这段用来载入视图的代码,此时完整的如代码20-8所示。代码20-8 在Controller中载入视图()load->view('helloview');}function saylucky(){echo 'It's time to say "Good Luck"!';}function sayhello($name){echo "Hello, $name !";}}?>4)此时再通过地址localhost/ch20//hello浏览,将看到如图20.7所示的执389励志照亮人生 编程改变命运零基础学 PHP行结果。5)通过这段代码,读者了解了如何载入一个视图。但视图中经常需要动态数据的内容,下面就介绍如何处理含有动态数据的视图。动态数据通过控制器以一个数组或对象的形式传入视图,这个数组或对象作为视图载入方法的第二个参数,如代码20-9所示。代码20-9 向视图中添加动态数据()load->view('helloview1',$data);}function saylucky(){echo 'It's time to say "Good Luck"!';}function sayhello($name){echo "Hello, $name !";}}?>6)此时访问会看到如图20.8所示的执行结果,从图20.8可以看出浏览器上的页面标题和页面的heading文字都更换成动态数据内容。图20.7 在Controller中载入视图图20.8 向视图添加动态数据代码20-9的第6、7两行定义了数组$data的两个元素,这两个元素分别是页面的标题和页面的文本内容。代码第8行向载入视图的方法view()传入第2个参数,该参数即代码前两行定义的数组。7)最后还需要修改,将在其中添加输出数据的PHP代码,修改后按保存在application/views/目录下,修改后的代码如下所示,其中第3行和第6行有输出数据的PHP代码。励志照亮人生 编程改变命运390
第20章PHP与MVC开发模式
版权声明:本文标题:PHP与MVC开发模式 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.freenas.com.cn/free/1708263613h517983.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论