|
|
|
|
移动端

1.4.1 MVC框架模式的实现

《Yii框架深度剖析》第1章初识PHP框架技术,本章首先介绍PHP语言发展历史及其适合的应用领域,然后讲解PHP框架技术的概念并仿照Yii框架源码自定义一个框架,其中包括MVC框架模式、单入口模式和应用(前端控制器模式)的实现。读者在充分了解了这部分内容后,将正式进入到Yii框架的学习。本节为大家介绍MVC框架模式的实现。

作者:刘琨来源:人民邮电出版社|2017-11-23 17:18

年前最后一场技术盛宴 | 1月27日与京东、日志易技术大咖畅聊智能化运维发展趋势!


1.4 自定义框架

在学习Yii框架前,我们先自定义一个框架,这样能更好地掌握框架技术的工作机制,为以后学习Yii框架做好准备。同时,设计一个自己的PHP框架并一步步地实现,可以及时融入最新的思想和理念。更重要的是,属于自己的框架可以根据项目的需要为其量身定制。

那么,就先从实现MVC框架模式开始。

1.4.1 MVC框架模式的实现(1)

Yii使用了Web开发中广泛采用的MVC框架模式,因此,使用者在使用Yii建立应用系统时,必须对MVC的原理有一些了解。MVC一直以来是Yii框架初学者很难跨过的一个障碍,本节仿照Yii框架代码实现MVC的软件架构,希望能够通过深入浅出的方式,让读者对MVC有清楚的认识。

1.MVC框架模式的工作原理

传统的基于PHP语言的Web应用程序把PHP代码和HTML、CSS、JavaScript代码混合在一起,这样不利于代码的后期维护,同时也不利于程序功能的扩展。基于MVC的应用程序,把应用程序中的各个功能独立出来,可以很好地实现程序功能的分工合作,对于代码的维护和扩展也十分方便。

MVC是一种目前广泛流行的框架模式。近年来,随着PHP的成熟,它正在成为在LAMP平台上推荐的一种框架设计模式,也是广大PHP开发者非常感兴趣的框架设计模式,并有不断成长的趋势。随着网络应用的快速增加,MVC模式对于Web应用的开发无疑是一种非常先进的设计思想。无论用户选择哪种语言,无论应用多么复杂,都能为用户理解分析应用模型提供最基本的分析方法,为用户构造产品提供清晰的设计框架,为用户的软件工程提供规范的依据。MVC的设计思想是把一个应用的输入、处理和输出流程按照模型(Model)、视图(View)和控制器(Controller)的方式进行分离,这样的一个应用分成3个层——模型层、视图层和控制层,下面分别进行介绍。

(1)视图

视图是用户看到的并与之交互的界面。视图可以向用户显示相关的数据,并能接收用户的输入数据,但它并不进行任何实际的业务处理。视图可以向模型查询业务状态,但不能改变模型。视图还能接收模型发出的数据更新事件,从而对用户界面进行同步更新。作为视图,它只是作为一种输出数据并允许用户操作的方式。

(2)模型

在MVC的3个部件中,模型是主体部分,包含业务数据和业务逻辑,同时负责访问和更新持久化数据。一个模型能为多个视图提供数据,每个视图都从不同角度来表达模型。由于应用于模型的代码只需写一次就可以被多个视图重用,因此降低了代码的重复性。

(3)控制器

控制器负责协调整个应用程序的运转,作用就是接收浏览器端的请求。它接收用户的输入并调用模型和视图去完成用户的需求,当用户单击Web页面中的超链接或发送HTML表单时,控制器本身不输出,只是接收请求并决定调用哪个模型去处理浏览器端发出的请求,然后确定用哪个视图来显示模型处理返回的数据。

MVC处理过程如图1-3所示,首先控制器接收用户的请求,并决定应该调用哪个模型来处理;然后模型根据用户请求进行相应的业务逻辑处理,并返回数据;最后控制器调用相应的视图来格式化模型返回的数据,并通过视图呈现给用户。

2.MVC模式的优点

使用PHP开发出来的Web应用,初始的开发模板就是混合的数据编程。例如,直接向数据库发送请求并用HTML显示,开发速度往往比较快,但由于数据页面的分离不是很直接,因此很难体现出业务模型的样子或者模型的重用性。产品设计弹性力度很小,很难满足用户的多样化的需求。MVC要求对应用分层,虽然要进行额外的工作,但产品的结构清晰,产品的应用通过模型可以得到更好的体现。

首先,最重要的是应该有多个视图对应一个模型的能力。在目前用户需求快速变化的情况下,可能有多种方式访问应用的要求。例如,订单模型可能有本系统的订单,也有网上订单,或者其他系统的订单,但对于订单的处理都是一样,也就是说,订单的处理是一致的。按照MVC设计模式,一个订单模型以及多个视图即可解决问题。这样减少了代码的复制,即减少了代码的维护量,一旦模型发生改变,也易于维护。其次,由于模型返回的数据不带任何显示格式,因而这些模型也可直接应用于接口的使用。再次,由于一个应用被分离为3层,因此有时改变其中的一层就能满足应用的改变。面对一个应用的业务流程或者业务规则的改变,只需改动MVC的模型层。

控制器还有一个好处,就是可以用它来连接不同的模型和视图去完成用户的需求,这样它可以为构造应用程序提供强有力的手段。给定一些可重用的模型和视图,控制器可以根据用户的需求选择模型进行处理,然后通过视图将处理结果显示给用户。

最后,MVC还有利于软件工程化管理。由于不同的层各司其职,每一层不同的应用具有某些相同的特征,因此有利于通过工程化、工具化特性产生管理程序代码。

综上所述,MVC是构筑软件非常好的框架模式,即将业务处理与显示分离,强制地将应用分为模型、视图及控制层。总之,MVC模式会使得应用更加强壮,更加有弹性,更加个性化。

3.MVC框架模式的实现

在实现MVC框架模式之前,我们先来介绍一下不使用MVC的开发流程。这里有一个网站的3个页面,分别是首页(index.html)、列表页(arc_list.html)和内容页(article.html)。这3个页面都是静态页面。接下来实现由静态页面改写成PHP动态页面,以便能及时从数据库中读取最新内容。这里只实现首页中的“行业百科”模块,效果如图1-4所示。

静态页面index.html中“行业百科”模块代码如下。

  1. <div class="title2 indextt4"> 
  2. <span><a title=行业百科 href="#">行业百科</a></span> 
  3. <em><a href="#">更多 &gt;&gt; </a></em> 
  4. </div> 
  5. <div class="rightList2 marginbtm15"> 
  6. <ul class=ulRightList1s> 
  7. <li><a title=洗碗机分类 href="#" target=_blank>洗碗机分类</a></li> 
  8. <li><a title=家用全自动洗碗机分类 href="#" target=_blank>家用全自动  
  9. 洗碗机分类</a></li> 
  10. <li><a title=洗碗机在中国的三起三落 href="#" target=_blank>洗碗机在  
  11. 中国的三起三落</a></li> 
  12. <li><a title=家用全自动洗碗机发展历史 href="#" target=_blank>家用全  
  13. 自动洗碗机发展历史</a></li> 
  14. <li><a title=什么是洗碗机? href="#" target=_blank>什么是洗碗机?  
  15. </a></li> 
  16. </ul> 
  17. </div> 

使用PHP语言从数据库中读取“行业百科”栏目下的文章标题,重新编写成index.php文件,代码如下所示。

  1. <div class="title2 indextt4"> 
  2. <span><a title=行业百科 href="#">行业百科</a></span> 
  3. <em><a href="#">更多 &gt;&gt; </a></em> 
  4. </div> 
  5. <div class="rightList2 marginbtm15"> 
  6. <ul class=ulRightList1s> 
  7. <?php 
  8. $dbh = new PDO('mysql:dbname=dscms;host=127.0.0.1','root','aa09090909');  
  9. $dbh->exec("set names 'utf8'");  
  10. $query = "SELECT title FROM ds_article WHERE cid='14'";  
  11. try {  
  12. //执行SELECT 查询,并返回PDOstatement 对象  
  13. $pdostatement = $dbh->query($query);  
  14. $result=$pdostatement->fetchAll();  
  15. foreach ($result as $row)  
  16. {  
  17. ?> 
  18. <li><A title=<?php echo $row["title"]; ?> href="#" 
  19. target=_blank><?php echo $row["title"];?></A></li> 
  20. <?php 
  21. }  
  22. } catch (PDOException $e) {  
  23. echo $e->getMessage();  
  24. }  
  25. ?> 
  26. </ul> 
  27. </div> 

实现了首页中“行业百科”从数据库查询功能后,首页中其他功能,还有列表页、内容页,实现过程和“行业百科”类似,这里就不列举了。

如此编写代码是很多初学者经历的一个阶段,就是将PHP代码和HTML、CSS、JavaScript代码混合在一起使用。如果有人之前这样去做的话,能否体会出代码混合在一起编写所带来的麻烦?

首先就是不利于代码的重复使用,如上文中的“行业百科”模块。如果在列表页和内容页中也有一样的模块,则需要重复编写,或者把这部分的代码放到一个文件中,频繁使用include语句去调用。或者代码连重复利用都不行,如数据库操作等。其次就是不利于较大项目的团队合作,如后端开发不需要使用HTML、CSS和JavaScript等技术;前端开发不需要使用数据库、PHP开发。最后,不利于代码的后期扩展,如在后期的项目维护过程中,代码混杂,层次不清,将导致重复修改。

如何解决这些不利于软件开发的问题呢?毫无疑问,MVC框架模式就能解决,具体处理流程如下。

步骤1:创建models/Article.php,并在文件中定义文章表模型类Article,其中的find()方法返回查询数据的结果。

  1. <?php 
  2. class Article  
  3. {  
  4. public function find()  
  5. {  
  6. $dbh = new PDO('mysql:dbname=dscms;host=127.0.0.1','root','');  
  7. $dbh->exec("set names 'utf8'");  
  8. $query = "SELECT title FROM ds_article WHERE cid='14'";  
  9. try {  
  10. //执行SELECT 查询,并返回PDOstatement 对象  
  11. $pdostatement = $dbh->query($query);  
  12. return $result=$pdostatement->fetchAll();  
  13. } catch (PDOException $e) {  
  14. echo $e->getMessage();  
  15. }  
  16. }  
  17. }  
  18. ?> 

步骤2:在framework/framework.php文件中创建控制器的基类CController,并实现控制器渲染视图方法render(),这个方法的功能是加载指定目录下的视图文件,并将控制器中的数据传递到视图文件中。

  1. <?php 
  2. class CController{  
  3. /**  
  4. 加载指定目录下的模板文件,并将控制器中的数据传递到视图文件中  
  5. @param string $fileName 提供模板文件的文件名  
  6. @param array 变量名=>变量值  
  7. */  
  8. public function render($viewName, $data){  
  9. extract($data, EXTR_PREFIX_SAME,'data');//将数组$data 变成变量的形式  
  10. require($viewName);//包含视图文件  
  11. }  
  12. }  
  13. ?> 

喜欢的朋友可以添加我们的微信账号:

51CTO读书频道二维码


51CTO读书频道活动讨论群:365934973

【责任编辑:book TEL:(010)68476606】

回书目   上一节   下一节
点赞 0
分享:
大家都在看
猜你喜欢

读 书 +更多

勇敢者的新世界

这是一个最坏的年代,J2EE Web开发技术已经迟滞多年;这是一个最好的年代,J2EE Web开发技术的新变革留给勇于创新的人! 采用Apusic Opera...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊