深入浅析用PHP实现MVC


Posted in PHP onMarch 02, 2016

在PHP中使用MVC越来越流行了,特别是在一些开源的框架当中。MVC足以应对大多数的情况,但还有一些情况是其不太适合的,如比较简单的个人博客,对于只有几百篇文章量级的博客,使用MVC让人觉得有些太复杂了;同样对于新浪等门户网站,使用MVC,将有大量的文件被加载,对于速度的影响是无法接受的

传统的面相过程式的开发方式在处理中型以上的应用时,就开始显得力不从心。即便我们能够快速的完成需求,但是在需求发生变更后或者进行后期维护的时候,我们会深深地陷入我们早期搭建的陷阱中。所以,使用面向对象的方式来实现MVC模式,将为我们梳理程序的架构提供一个清晰的思路。

什么是MVC?

深入浅析用PHP实现MVC

关于MVC的定义和解释,可以说多种多样。我们可以在Wiki或者[2]中找到更为详尽的解释,这里我并不打算,也没有能力进行深入的讲解,从PHP开发的角度来讲,MVC可以概括为:

视图(The View):

一说到视图,我们很多人都会想到模板引擎(诸如Smarty等等)。其实就是各种各样的输出,比如说html模板和Javascript文件等。

模块(The Model)

模块代表了程序的逻辑,在企业应用中通常称为业务逻辑层。一般来讲,这一层完成的工作是把原始的数据处理成按照我们设计的数据结构存储的有意义的数据序列,并将这些数据交给视图去处理。通常情况下, 模块中会利用一个数据抽象类来进行与数据操作有关的处理。

Model通常包含了哪些用来同数据库打交道的函数。

控制器(The Controller)

控制器使所有WEB应用的第一站,他接受收到的参数,比如$_GET变量,然后做出相应的反应。

关于MVC的是否适合PHP的争论也很多,人们不断的讨论MVC是否适合PHP[3],现在也已经有了很多的MVC框架,诸如PHP MVC Frameworks中列出的[4]。那么,为什么人们这么热衷于MVC,我们为什么要使用MVC在我们的设计中呢。

为什么用MVC?

MVC最早是用来解决桌面GUI的编程问题,最早的MVC框架应该是Sun在1999年提出的Model 2,后来演变成了Struts。MVC带给人们深刻的印象,但是我们在使用的过程中,却并没有认真的想过为什么使用MVC。

在传统的桌面应用中,一旦Model中有时间发生,我们可以主动的让View界面进行刷新,从而展示后台发生的变化。而在Web应用中,我们似乎限于传统的 Http的Request/Response的方式,我们似乎没有办法让用户端进行更新。这一段讨论,并不是认为MVC不能够用来进行WEB应用的开发,而是觉得从某种程度上来说,他还不是最合适的。

关于使用MVC的争论还有很多[1],但是相信所有习惯了使用MVC来组织自己的项目的人,让他选择一个新的项目构架时,一定不会放弃MVC。

如何实现MVC?

下面是一个超级简单的MVC结构实现,甚至连数据源都用了一个内置的固定数组,虽然简单,但其实众多的PHP Framework核心实现的思想应该和这个是差不多的,只不过一些framework提供了更多的方便开发者使用的工具,我也想自己来实现一个PHP的框架,目前正在着手策划中,也希望自己能够从框架的开发中学习到更多的PHP设计思想和方法。

Controller.php

include 'Model.php';
include 'View.php';
class Controller {
private $model = '';
private $view = '';
public function Controller(){
$this->model = new Model();
$this->view = new View();
}
public function doAction( $method = 'defaultMethod', $params = array() ){
if( empty($method) ){
$this->defaultMethod();
}else if( method_exists($this, $method) ){
call_user_func(array($this, $method), $params);
}else{
$this->nonexisting_method();
}
}
public function link_page($name = ''){
$links = $this->model->getLinks();
$this->view->display($links);
$result = $this->model->getResult($name);
$this->view->display($result);
}
public function defaultMethod(){
$this->br();
echo "This is the default method. ";
}
public function nonexisting_method(){
$this->br();
echo "This is the noexisting method. ";
}
public function br(){
echo "";
}
}
$controller = new Controller();
$controller->doAction('link_page', 'b');
$controller->doAction();
==================================
Model.php
class Model {
private $database = array(
"a" => "hello world",
"b" => "ok well done",
"c" => "good bye",
);
//@TODO connect the database
//run the query and get the result
public function getResult($name){
if( empty($name) ){
return FALSE;
}
if( in_array($name, array_keys( $this->database ) ) ){
return $this->database[$name];
}
}
public function getLinks(){
$links = "Link A ";
$links.= "Link B ";
$links.= "Link C ";
return $links;
}
}
====================================================
View.php
class View {
public function display($output){
// ob_start();
echo $output;
}
}
PHP 相关文章推荐
PHP扩展编写点滴 技巧收集
Mar 09 PHP
thinkPHP的Html模板标签使用方法
Nov 13 PHP
PHP is_subclass_of函数的一个BUG和解决方法
Jun 01 PHP
php实现的九九乘法口诀表简洁版
Jul 28 PHP
thinkphp中html:list标签传递多个参数实例
Oct 30 PHP
19个Android常用工具类汇总
Dec 30 PHP
php生成4位数字验证码的实现代码
Nov 23 PHP
php查找字符串中第一个非0的位置截取
Feb 27 PHP
删除PHP数组中头部、尾部、任意元素的实现代码
Apr 10 PHP
php无限极分类实现方法分析
Jul 04 PHP
解决在laravel中leftjoin带条件查询没有返回右表为NULL的问题
Oct 15 PHP
thinkphp5框架路由原理与用法详解
Feb 11 PHP
解析WordPress中控制用户登陆和判断用户登陆的PHP函数
Mar 01 #PHP
编写PHP脚本清除WordPress头部冗余代码的方法讲解
Mar 01 #PHP
WordPress的文章自动添加关键词及关键词的SEO优化
Mar 01 #PHP
详解WordPress中的头像缓存和代理中的缓存更新方法
Mar 01 #PHP
php编程每天必学之表单验证
Mar 01 #PHP
实例讲解PHP设计模式编程中的简单工厂模式
Feb 29 #PHP
PHP Try-catch 语句使用技巧
Feb 28 #PHP
You might like
PHP Array交叉表实现代码
2010/08/05 PHP
Laravel 5 框架入门(一)
2015/04/09 PHP
PHP MVC框架路由学习笔记
2016/03/02 PHP
浅谈php数组array_change_key_case() 函数和array_chunk()函数
2016/10/22 PHP
php实现socket推送技术的示例
2017/12/20 PHP
PHPExcel实现的读取多工作表操作示例
2020/04/14 PHP
Z-Blog中用到的js代码
2007/03/15 Javascript
Mootools 1.2教程(21)——类(二)
2009/09/15 Javascript
HTML node相关的一些资料整理
2010/01/01 Javascript
js中传递特殊字符(+,&)的方法
2014/01/16 Javascript
如何防止JavaScript自动插入分号
2015/11/05 Javascript
Bootstrap3.0建站教程(一)之bootstrap表单元素排版
2016/06/01 Javascript
深入理解requestAnimationFrame的动画循环
2016/09/20 Javascript
JavaScript注入漏洞的原理及防范(详解)
2016/12/04 Javascript
js实现百度搜索提示框
2017/02/05 Javascript
React Native实现进度条弹框的示例代码
2017/07/17 Javascript
AngularJS双向数据绑定原理之$watch、$apply和$digest的应用
2018/01/30 Javascript
用p5.js制作烟花特效的示例代码
2018/03/21 Javascript
vue中使用echarts制作圆环图的实例代码
2018/07/27 Javascript
对layui初始化列表的CheckBox属性详解
2019/09/13 Javascript
ES6函数实现排它两种写法解析
2020/05/13 Javascript
用Python编写一个每天都在系统下新建一个文件夹的脚本
2015/05/04 Python
python中Apriori算法实现讲解
2017/12/10 Python
Python使用百度翻译开发平台实现英文翻译为中文功能示例
2019/08/08 Python
Europcar美国/加拿大:预订汽车或卡车租赁服务
2018/11/13 全球购物
C++:局部变量能否和全局变量重名
2014/03/03 面试题
读书之星事迹材料
2014/05/12 职场文书
食堂标语大全
2014/06/11 职场文书
舞蹈教育学专业求职信
2014/06/29 职场文书
车辆转让协议书
2014/09/24 职场文书
用人单位聘用意向书
2015/05/11 职场文书
2015年街道除四害工作总结
2015/05/15 职场文书
幼儿园教师教育随笔
2015/08/14 职场文书
让文件路径提取变得更简单的Python Path库
2021/05/27 Python
Python 如何将integer转化为罗马数(3999以内)
2021/06/05 Python
超越Nginx的Web服务器caddy优雅用法
2022/06/21 Servers