PHP MVC留言本实例.docx
- 文档编号:4728459
- 上传时间:2022-12-08
- 格式:DOCX
- 页数:12
- 大小:21.14KB
PHP MVC留言本实例.docx
《PHP MVC留言本实例.docx》由会员分享,可在线阅读,更多相关《PHP MVC留言本实例.docx(12页珍藏版)》请在冰豆网上搜索。
PHPMVC留言本实例
最简单的PHPMVC留言本实例[已修正]
这个帖子发布以后有朋友指出例子中V直接操作M不符合MVC原则,现在对代码做了修改:
在C中调用M中的方法返回数据(如全部留言数据),将M返回的数据传递给V,这样C操作M和V,V不再直接与M联系。
欢迎大家多多拍砖!
写完那篇“写给懂C语言的人的PHP基本语法入门”后一直在学习PHP5的OOP,目的很简单,就是想研究MVC的PHP实现,所以,兴趣很快转移到MVC上面,网上有很多长篇大论,但是看完了我还是不能写出一个最简单的MVC程序,我这个人学东西有个习惯,那就是先要掌握一个最简单的“HelloWorld”,然后再以此为基础扩展开去,否则心里没底,一头雾水。
经过一番搜索,找到了一篇翻译文章(作者:
HarryFuecks翻译:
EasyChenURL:
原文URL:
..._controller_pattern)作者以商品目录浏览为例,给出了完整的MVC架构代码。
仔细一看,发现他的C和V是继承关系,耦合很紧,似乎不是很理想,但马上又看到了作者的第二个版本(
标题上我把这个留言板叫最简单的,其实应该叫最简陋的,因为把全部注意力集中在MVC模式设计和实现上,所以UI方面几乎没有一点修饰。
之所以在这里跟大家分享这个东西,是因为我自己通过读该老外的代码并仿照着写留言板对MVC的概念和具体实现有了些认识,希望了解MVC具体实现的朋友可以参考一下。
首先通俗地说说我对MVC的理解:
Model是负责干活的,它干的活主要是从数据库中获取需要的数据以及对获取的数据按照业务逻辑进行加工处理,至于为什么要干某件活,何时干某件活它一概不管,而这正是Controller的职责,Controller像个餐馆招待,接到食客的需求,马上传达给厨房,Model就是大厨。
View负责最终把菜端上桌,摆在合适的位置上。
比如说客人来了要了个糖醋鲤鱼,接待客人的是Controller,它会通知Model做一道糖醋鲤鱼,做好之后它又会招呼View把菜端上桌,View知道这是主菜,它会把它摆在桌子中央。
MVC的最大优势就在于把数据处理、流程控制和UI显示较好地分离开来,便于程序的开发和维护。
好了,下面看具体实现。
这个小程序一共包含6个文件,其中index.php是程序入口、post.htm是留言表单、在lib文件夹里Model、View、Controller三个文件分别实现MVC,DataAccess是一个简单的数据库访问类。
php
/**
*一个用来访问MySQL的类
*仅仅实现演示所需的基本功能,没有容错等
*代码未作修改,只是把注释翻译一下,加了点自己的体会
*/
classDataAccess{
var$link_id;//用于存储数据库连接
var$query_id;//用于存储查询源
//!
构造函数.
/**
*创建一个新的DataAccess对象
*@param$host数据库服务器名称
*@param$user数据库服务器用户名
*@param$pass密码
*@param$db数据库名称
*/
function__construct($host,$user,$pass,$db){
$this->link_id=mysql_pconnect($host,$user,$pass);//连接数据库服务器
mysql_select_db($db,$this->link_id);//选择所需数据库
mysql_query("setnamesutf8;");
}
//!
执行SQL语句
/**
*执行SQL语句,获取一个查询源并存储在数据成员$query中
*@param$sql被执行的SQL语句字符串
*@returnvoid
*/
functionquery($sql){
$this->query_id=mysql_unbuffered_query($sql,$this->link_id);//Performqueryhere
if($this->query_id)returntrue;
elsereturnfalse;
}
//!
获取结果集
/**
*以数组形式返回查询结果的所有记录
*@returnmixed
*/
functionfetchRows($sql){
$this->query($sql);
$arr=array();
$i=0;
while($row=mysql_fetch_array($this->query_id,MYSQL_ASSOC))
//MYSQL_ASSOC参数决定了数组键名用字段名表示
{$arr[$i]=$row;
$i++;
}
return$arr;
}
}
?
>
复制代码
下面再来介绍一下Model类。
这个类也很简单,里面的函数一看就知道,是针对各种数据操作的,它通过DataAccess访问数据库。
php
//!
Model类
/**
*它的主要部分是对应于留言本各种数据操作的函数
*如:
留言数据的显示、插入、删除等
*/
classModel{
var$dao;//DataAccess类的一个实例(对象)
//!
构造函数
/**
*构造一个新的Model对象
*@param$dao是一个DataAccess对象
*该参数以地址传递(&$dao)的形式传给Model
*并保存在Model的成员变量$this->dao中
*Model通过调用$this->dao的fetch方法执行所需的SQL语句
*/
function__construct(&$dao){
$this->dao=$dao;
}
functionlistNote(){//获取全部留言
$notes=$this->dao->fetchRows("SELECT*FROMnoteORDERBYtimedateDESC");
return$notes;
}
functionpostNote(){//插入一条新留言
$name=$_POST['username'];
$email=$_POST['email'];
$content=$_POST['content'];
$timedate=time()+8*3600;
$sql="INSERTINTOnote(name,email,content,timedate)VALUES
('".$name."','".$email."','".$content."','".$timedate."')";
//echo$sql;//对于较复杂的合成SQL语句,
//调试时用echo输出一下看看是否正确是一种常用的调试技巧
if($this->dao->query($sql))returntrue;
elsereturnfalse;
}
functiondeleteNote(){//删除一条留言,$id是该条留言的id
$sql="DELETEFROMnoteWHEREid=".$_GET['id'];
if($this->dao->query($sql))returntrue;
elsereturnfalse;
}
}
?
>
复制代码
看完这两个类之后你可能会发现这与以前我们写程序差不多,的确现在还闻不到MVC的味道,如果你不懂MVC,在这两个类的基础上你完全可以开始写你以前的程序了。
例如要显示全部留言,只需要写入下代码:
php
require_once('lib/DataAccess.php');
require_once('lib/Model.php');
$dao=&newDataAccess('localhost','root','password','test');
$model=&newModel($dao);
$notes=$model->listNote();
……
?
>
复制代码
很亲切吧,呵呵。
有了这个“感情基础”你就不会对MVC望而生畏了,下面我们就要上今天的主菜了,那就是“Controller”闪亮登场!
先大体浏览一下主要结构,它包括一个Controller类以及派生出的三个子类(listController对应显示留言功能、postController对应发表留言功能以及deleteController对应删除留言功能)。
php
//!
Controller
/**
*控制器将$_GET['action']中不同的参数(list、post、delete)
*对应于完成该功能控制的相应子类
*/
classController{
var$model;//Model对象
var$view;//View对象
//!
构造函数
/**
*构造一个Model对象存储于成员变量$this->model;
*/
function__construct(&$dao){
$this->model=&newModel($dao);
}
functiongetView(){//获取View函数
//返回视图对象view
//对应特定功能的Controller子类生成对应的View子类的对象
//通过该函数返回给外部调用者
return$this->view;
}
}
//用于控制显示留言列表的子类
classlistControllerextendsController{//extends表示继承
function__construct(&$dao){
parent:
:
__construct($dao);//继承其父类的构造函数
//该行的含义可以简单理解为:
//将其父类的构造函数代码复制过来
$notes=$this->model->listNote();
$this->view=&newlistView($notes);
//创建相应的View子类的对象来完成显示
}
}
//用于控制添加留言的子类
classpostControllerextendsController{
function__construct(&$dao){
parent:
:
__construct($dao);
if($this->model->postNote())$success=1;
else$success=0;
$this->view=&newpostView($success);
}
}
//用于控制删除留言的子类
classdeleteControllerextendsController{
function__construct(&$dao){
parent:
:
__construct($dao);
if($this->model->deleteNote())$success=1;
else$success=0;
$this->view=&newdeleteView($success);
}
}
?
>
复制代码
大体浏览之后,你一定打算开始仔细研究它了吧,别急,为了心中有数,我们先从宏观着眼,先看看总入口index.php是如何调用Controller的:
php
//!
index.php总入口
/**
*index.php的调用形式为:
*显示所有留言:
index.php?
action=list
*添加留言:
index.php?
action=post
*删除留言:
index.php?
action=delete&id=x
*/
require_once('lib/DataAccess.php');
require_once('lib/Model.php');
require_once('lib/View.php');
require_once('lib/Controller.php');
//创建DataAccess对象(请根据你的需要修改参数值)
$dao=&newDataAccess('localhost','root','yourpasswordhere','notebook');
//根据$_GET["action"]取值的不同调用不同的控制器子类
$action=$_GET["action"];
switch($action)
{
case"post":
$controller=&newpostController($dao);break;
case"list":
$controller=&newlistController($dao);break;
case"delete":
$controller=&newdeleteController($dao);break;
default:
$controller=&newlistController($dao);break;//默认为显示留言
}
$view=$controller->getView();//获取视图对象
$view->display();//输出HTML
?
>