目錄
PHP代码:
首頁 後端開發 php教程 一个简略的php MVC实例

一个简略的php MVC实例

Jun 13, 2016 pm 01:14 PM
controller function gt model this

一个简单的php MVC实例

原文 http://jcodecraeer.com/a/phpjiaocheng/2012/0305/10.html

?

这个小程序一共包含6个文件,其中index.php是程序入口、post.htm是留言表单、在lib文件夹里Model、View 、Controller三个文件分别实现MVC,DataAccess是一个简单的数据库访问类。其实这个程序是国外的一个人写的。

PHP代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<?php
/**
* 一个用来访问MySQL的类
* 仅仅实现演示所需的基本功能,没有容错等
* 代码未作修改,只是把注释翻译一下,加了点自己的体会
*/
class DataAccess {
var $db; //用于存储数据库连接
var $query; //用于存储查询源
//! 构造函数.
/**
* 创建一个新的DataAccess对象
* @param $host 数据库服务器名称
* @param $user 数据库服务器用户名
* @param $pass 密码
* @param $db 数据库名称
*/
function __construct($host,$user,$pass,$db) {
$this->db=mysql_pconnect($host,$user,$pass); //连接数据库服务器
mysql_select_db($db,$this->db); //选择所需数据库
//特别注意$db和$this->db的区别
//前者是构造函数参数
//后者是类的数据成员
}
//! 执行SQL语句
/**
* 执行SQL语句,获取一个查询源并存储在数据成员$query中
* @param $sql 被执行的SQL语句字符串
* @return void
*/
function fetch($sql) {
$this->query=mysql_unbuffered_query($sql,$this->db); // Perform query here
}
//! 获取一条记录
/**
* 以数组形式返回查询结果的一行记录,通过循环调用该函数可遍历全部记录
* @return mixed
*/
function getRow () {
if ( $row=mysql_fetch_array($this->query,MYSQL_ASSOC) )
//MYSQL_ASSOC参数决定了数组键名用字段名表示
return $row;
else
return false;
}
}
?>

?

下面再来介绍一下Model类。
这个类也很简单,里面的函数一看就知道,是针对各种数据操作的,它通过DataAccess访问数据库。


PHP代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?php
//! Model类
/**
* 它的主要部分是对应于留言本各种数据操作的函数
* 如:留言数据的显示、插入、删除等
*/
class Model {
var $dao; //DataAccess类的一个实例(对象)
//! 构造函数
/**
* 构造一个新的Model对象
* @param $dao是一个DataAccess对象
* 该参数以地址传递(&$dao)的形式传给Model
* 并保存在Model的成员变量$this->dao中
* Model通过调用$this->dao的fetch方法执行所需的SQL语句
*/
function __construct(&$dao) {
$this->dao=$dao;
}
function listNote() { //获取全部留言
$this->dao->fetch("SELECT * FROM note");
}
function postNote($name,$content) { //插入一条新留言
$sql = "INSERT INTO `test`.`note`
(`id`, `name`, `content`, `ndate`, `add`)
VALUES (NULL, '$name', '$content', NULL, NULL);";
//echo $sql; //对于较复杂的合成SQL语句,<br>
//调试时用echo输出一下看看是否正确是一种常用的调试技巧
$this->dao->fetch($sql);
}
function deleteNote($id) { //删除一条留言,$id是该条留言的id
$sql = "DELETE FROM `test`.`note` WHERE `id`=$id;";
//echo $sql;
$this->dao->fetch($sql);
}
function getNote() { //获取以数组形式存储的一条留言
//View利用此方法从查询结果中读出数据并显示
if ( $note=$this->dao->getRow() )
return $note;
else
return false;
}
}
?>

?

看完这两个类之后你可能会发现这与以前我们写程序差不多,的确现在还闻不到MVC的味道,如果你不懂MVC,在这两个类的基础上你完全可以开始写你以前的程序了。例如要显示全部留言,只需要写入下代码:



PHP代码:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
require_once('lib/DataAccess.php');
require_once('lib/Model.php');
$dao=& new DataAccess ('localhost','root','','test');
$model=& new Model($dao);
$model->listNote();
while ($note=$model->getNote())
{
$output.="姓名:$note[name]<br> 留言:<br> $note[content] <br> <hr>";
}
echo $output;
?>

?

很亲切吧,呵呵。
有了这个“感情基础”你就不会对MVC望而生畏了,下面我们就要上今天的主菜了,那就是“Controller”闪亮登场!
先大体浏览一下主要结构,它包括一个Controller类以及派生出的三个子类(listController对应显示留言功能、postController对应发表留言功能以及deleteController对应删除留言功能)。

PHP代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<?php
//! Controller
/**
* 控制器将$_GET['action']中不同的参数(list、post、delete)
* 对应于完成该功能控制的相应子类
*/
class Controller {
var $model; // Model 对象
var $view; // View 对象
//! 构造函数
/**
* 构造一个Model对象存储于成员变量$this->model;
*/
function __construct (& $dao) {
$this->model=& new Model($dao);
}
function getView() { //获取View函数
//返回视图对象view
//对应特定功能的Controller子类生成对应的View子类的对象
//通过该函数返回给外部调用者
return $this->view;
}
}
//用于控制显示留言列表的子类
class listController extends Controller{ //extends表示继承
function __construct (& $dao) {
parent::__construct($dao); //继承其父类的构造函数
//该行的含义可以简单理解为:
//将其父类的构造函数代码复制过来
$this->view=& new listView($this->model);
//创建相应的View子类的对象来完成显示
//把model对象传给View子类供其获取数据
}
}
//用于控制添加留言的子类
class postController extends Controller{
function __construct (& $dao, $post) {
parent::__construct($dao);
$this->view=& new postView($this->model, $post);
//$post的实参为$_POST数组
//表单中的留言项目存储在该系统数组中
}
}
//用于控制删除留言的子类
class deleteController extends Controller{
function __construct (& $dao, $id) {
parent::__construct($dao);
$this->view=& new deleteView($this->model, $id);
}
}
?>

?

大体浏览之后,你一定打算开始仔细研究它了吧,别急,为了心中有数,我们先从宏观着眼, 先看看总入口index.php是如何调用Controller的:

PHP代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<meta http-equiv="</code"> <code class="js string">"Content-Type" content="text/html; charset=gb2312" />
<title>PHP MVC留言板</title>
<a href="</code"><code class="js string">"post.htm">添加新留言
<p> </p>
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=& new DataAccess ('localhost','root','','test');
//根据$_GET["action"]取值的不同调用不同的控制器子类
$action=$_GET["action"];
switch (
$action)
{
case "post":
$controller=& new postController($dao,$_POST); break;
case "list":
$controller=& new listController($dao); break;
case "delete":
$controller=& new deleteController($dao,$_GET["id"]); break;
default:
$controller=& new listController($dao); break; //默认为显示留言
}
$view=$controller->getView(); //获取视图对象
$view->display(); //输出HTML
?>

?

看过index.php之后你就更清楚了吧,原来功能是通过$_GET[“action”]指定的,由一个switch结构分发,不同的功能对应不 同的Controller子类。现在可以滚上去(滚动页面上去的简称,绝非不洁用语^_^)仔细看看这个Controller代码了。注释应该很细了,不 懂的地方就去看看PHP5的OOP语法和概念吧,单纯看这些概念总是越看催眠效果越好,现在带着实际问题去看,应该有所不同吧。不过我还是建议你在完成这 个MVC的Hello World知道MVC是怎么回事之后下功夫打好OOP的基础,毕竟那是根本啊。
怎么样,Controller真是个光说 不练的家伙吧,看不到三行它就把你引向View了,那就看看View吧。
View里有对应的子类,负责相应功能的显示。理解了 Controller,View的代码就不难看了,难看的话也是因为混杂着HTML的原因,它所做的就是从Model获取所需的数据,然后塞到HTML 中。

PHP代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
<?php
//! View 类
/**
* 针对各个功能(list、post、delete)的各种 View子类
* 被Controller调用,完成不同功能的网页显示
*/
class View {
var
$model; //Model对象
var $output; //用于保存输出HTML代码 的字符串
//! 构造函数
/**
* 将参数中的Model对象接收并存储在成员变量$this->model中
* 供子类通 过model对象获取数据
*/
function __construct (&$model) {
$this->model=$model;
}
function
display() { //输出最终格式化的HTML数据
echo($this->output);
}
}
class
listView extends View //显示所有留言 的子类
{
function __construct(&$model)
{
parent::__construct(&$model); //继承父类的构造函数(详见Controller)
$this->model->listNote();
while ($note=$this->model->getNote()) //逐行获取数据
{
$this->output.="姓名:$note[name]<br> 留 言:<br> $note[content]
<a href="%5C%22%22</code"><code class="js plain">.$_SERVER['PHP_SELF']."?action=delete& amp;id=$note[id]\">删除

";
}
}
}
class
postView extends View //发表留言的子类
{
function __construct(&$model, $post)
{
parent::__construct(&$model);
$this->model->postNote($post[name],$post[content]);
$this->output="Note Post OK!
<a href="%5C%22%22</code"><code class="js plain">.$_SERVER[
'PHP_SELF']."?action=list\">查看";
}
}
class
deleteView extends View //删除留言的子类
{
function __construct(&$model, $id)
{
parent::__construct(&$model);
$this->model->deleteNote($id);
$this->output="Note Delete OK!
<a href="%5C%22%22</code"><code class="js plain">.$_SERVER[
'PHP_SELF']."?action=list\">查看";
}
}
?>

之所以UI方面写得如此简陋,是因为这些工作可以交给Smarty这样的模板去做,而我们这里就像集中精力研究MVC,不想把Smarty扯进来, 所以就这样凑合了,以后我们可以再把Smarty结合进来。
看了这个东西之后不知你是否对MVC的概念和实现更明白了一点。
我也是个初学 者,这是个依葫芦画瓢之作,目的就是想了解一下MVC,如果你是高手,我很想得到你的点评,这样的划分和架构是否符合MVC的理念?还有哪些应该改进之 处?
当然,大家都知道现在很多关于MVC的争论,这很正常,就像关于开发语言的争论一样,永无休止,学术上的争论有助于创新。作为我们学技术、用 技术而言,一 定要踏实深入学习,掌握了基本用法之后再去讨论,那才是更高层次的发展,在自己都搞不清的情况下在哪里争论只能是浪费时间。
下面说 说我体会到的MVC的好处,它的确给程序的功能扩展带来方便,比如这个例子我们想要增加一个根据用户名查询留言的功能,只需要在Model里增加一 个查询函数(突然发现这些函数的用法很像存储过程),Controller和View里增加相应的子类,这种分离带来的好处是程序功能模块可以即插即用, 再就是整个程序的逻辑非常清晰。我想,对于需求变动频繁的Web应用来说,这种特性也许是很有价值的。

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1666
14
CakePHP 教程
1425
52
Laravel 教程
1327
25
PHP教程
1273
29
C# 教程
1253
24
華為GT3 Pro和GT4的差異是什麼? 華為GT3 Pro和GT4的差異是什麼? Dec 29, 2023 pm 02:27 PM

許多用戶在選擇智慧型手錶的時候都會選擇的華為的品牌,其中華為GT3pro和GT4都是非常熱門的選擇,不少用戶都很好奇華為GT3pro和GT4有什麼區別,下面就給大家介紹一下二者。華為GT3pro和GT4有什麼差別一、外觀GT4:46mm和41mm,材質是玻璃鏡板+不鏽鋼機身+高分纖維後殼。 GT3pro:46.6mm和42.9mm,材質是藍寶石玻璃鏡+鈦金屬機身/陶瓷機身+陶瓷後殼二、健康GT4:採用最新的華為Truseen5.5+演算法,結果會更加的精準。 GT3pro:多了ECG心電圖和血管及安

SpringBoot掃描不到Controller怎麼解決 SpringBoot掃描不到Controller怎麼解決 May 14, 2023 am 08:10 AM

SpringBoot小白創建項目​​,掃描不到Controller一系列問題1.2.3.4.5.6.還有一個方法是在啟動服務類的入門,添加@ComponentScan(basePackages={“xxx.xxx.xx”,“xxx.xxx .xx”})裡面的是包的全限定名,可以為多個SpringBoot自訂controller無法掃描到SpringBoot自訂controller路由找不到,原因是啟動類別和自訂的Controller包不在同一級目錄下。官方建議application.java放的位

function是什麼意思 function是什麼意思 Aug 04, 2023 am 10:33 AM

function是函數的意思,是一段具有特定功能的可重複使用的程式碼區塊,是程式的基本組成單元之一,可以接受輸入參數,執行特定的操作,並傳回結果,其目的是封裝一段可重複使用的程式碼,提高程式碼的可重複使用性和可維護性。

修復:截圖工具在 Windows 11 中不起作用 修復:截圖工具在 Windows 11 中不起作用 Aug 24, 2023 am 09:48 AM

為什麼截圖工具在Windows11上不起作用了解問題的根本原因有助於找到正確的解決方案。以下是截圖工具可能無法正常工作的主要原因:對焦助手已開啟:這可以防止截圖工具開啟。應用程式損壞:如果截圖工具在啟動時崩潰,則可能已損壞。過時的圖形驅動程式:不相容的驅動程式可能會幹擾截圖工具。來自其他應用程式的干擾:其他正在運行的應用程式可能與截圖工具衝突。憑證已過期:升級過程中的錯誤可能會導致此issu簡單的解決方案這些適合大多數用戶,不需要任何特殊的技術知識。 1.更新視窗與Microsoft應用程式商店應用程

SpringBoot多controller如何加入URL前綴 SpringBoot多controller如何加入URL前綴 May 12, 2023 pm 06:37 PM

前言在某些情況下,服務的controller中前綴是一致的,例如所有URL的前綴都為/context-path/api/v1,需要為某些URL加上統一的前綴。能想到的處理辦法為修改服務的context-path,在context-path中加上api/v1,這樣修改全域的前綴能夠解決上面的問題,但存在弊端,如果URL存在多個前綴,例如有些URL需要前綴為api/v2,就無法區分了,如果服務中的一些靜態資源不想添加api/v1,也無法區分。下面透過自訂註解的方式實現某些URL前綴的統一添加。一、

Trezor冷錢包:Model One與Model T的特性與使用指南 Trezor冷錢包:Model One與Model T的特性與使用指南 Jan 19, 2024 pm 04:12 PM

在許多中心化交易所出現問題後,越來越多的幣圈投資者開始將資產轉移到冷錢包中,以減少中心化交易所帶來的風險。本文將介紹全球最早的冷錢包供應商Trezor,自2014年推出首款冷錢包至今,在全球多個國家銷售。 Trezor的產品包括2014年推出的ModelOne和2018年推出的進階版本ModelT。以下將繼續介紹這兩款產品與其他冷錢包的差異。什麼是Trezor冷錢包? 2014年,Trezor推出了第一款冷皮夾ModelOne。除了常見的BTC、ETH、USDT等幣種外,該錢包還支援超過1000種其

'enumerate()'函數在Python中的用途是什麼? 'enumerate()'函數在Python中的用途是什麼? Sep 01, 2023 am 11:29 AM

在本文中,我們將了解enumerate()函數以及Python中「enumerate()」函數的用途。什麼是enumerate()函數? Python的enumerate()函數接受資料集合作為參數並傳回一個枚舉物件。枚舉物件以鍵值對的形式傳回。 key是每個item對應的索引,value是items。語法enumerate(iterable,start)參數iterable-傳入的資料集合可以作為枚舉物件傳回,稱為iterablestart-顧名思義,枚舉物件的起始索引由start定義。如果我們忽

MySQL.proc表的作用與功能詳解 MySQL.proc表的作用與功能詳解 Mar 16, 2024 am 09:03 AM

MySQL.proc表的功能與功能詳解MySQL是一種流行的關係型資料庫管理系統,開發者在使用MySQL時常常會涉及到預存程序(StoredProcedure)的建立與管理。而MySQL.proc表則是一個非常重要的系統表,它儲存了資料庫中所有的預存程序的相關信息,包括預存程序的名稱、定義、參數等。在本文中,我們將詳細解釋MySQL.proc表的作用與功能

See all articles