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

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas

Ramai pengguna akan memilih jenama Huawei apabila memilih jam tangan pintar Antaranya, Huawei GT3pro dan GT4 adalah pilihan yang sangat popular. Apakah perbezaan antara Huawei GT3pro dan GT4? 1. Rupa GT4: 46mm dan 41mm, bahan cermin kaca + badan keluli tahan karat + cangkang belakang gentian resolusi tinggi. GT3pro: 46.6mm dan 42.9mm, bahannya ialah kaca nilam + badan titanium/badan seramik + cangkerang belakang seramik 2. GT4 yang sihat: Menggunakan algoritma Huawei Truseen5.5+ terkini, hasilnya akan lebih tepat. GT3pro: Penambahan elektrokardiogram ECG dan saluran darah serta keselamatan

Apabila pemula SpringBoot mencipta projek, Pengawal tidak boleh diimbas dan satu siri masalah ialah 1.2.3.4.5.6 Cara lain ialah menambah @ComponentScan(basePackages={"xxx.xxx.xx","xxx.xxx" apabila. memulakan kelas perkhidmatan) .xx”}) ialah nama pakej yang layak sepenuhnya, yang boleh digunakan untuk berbilang pengawal tersuai SpringBoot Laluan pengawal tersuai SpringBoot tidak boleh diimbas dan tidak ditemui kerana kelas permulaan dan pakej Pengawal tersuai tidak berada dalam direktori yang sama. Peletakan application.java yang disyorkan secara rasmi

Fungsi bermaksud fungsi. Ia adalah blok kod yang boleh digunakan semula dengan fungsi tertentu Ia boleh menerima parameter input, melakukan operasi tertentu, dan mengembalikan hasil daripada blok yang boleh digunakan semula. kod untuk meningkatkan kebolehgunaan semula dan kebolehselenggaraan kod.

Mengapa Alat Snipping Tidak Berfungsi pada Windows 11 Memahami punca masalah boleh membantu mencari penyelesaian yang betul. Berikut ialah sebab utama Alat Snipping mungkin tidak berfungsi dengan betul: Focus Assistant dihidupkan: Ini menghalang Snipping Tool daripada dibuka. Aplikasi rosak: Jika alat snipping ranap semasa pelancaran, ia mungkin rosak. Pemacu grafik lapuk: Pemacu yang tidak serasi mungkin mengganggu alat snipping. Gangguan daripada aplikasi lain: Aplikasi lain yang sedang berjalan mungkin bercanggah dengan Alat Snipping. Sijil telah tamat tempoh: Ralat semasa proses naik taraf boleh menyebabkan penyelesaian mudah ini sesuai untuk kebanyakan pengguna dan tidak memerlukan sebarang pengetahuan teknikal khusus. 1. Kemas kini apl Windows dan Microsoft Store

Prakata Dalam sesetengah kes, awalan dalam pengawal perkhidmatan adalah konsisten Contohnya, awalan semua URL ialah /context-path/api/v1, dan awalan bersatu perlu ditambahkan pada beberapa URL. Penyelesaian yang boleh difikirkan adalah untuk mengubah suai laluan konteks perkhidmatan dan menambah api/v1 pada laluan konteks global boleh menyelesaikan masalah di atas, tetapi terdapat kelemahan Jika URL mempunyai beberapa awalan URL memerlukan awalan Jika ia adalah api/v2, ia tidak dapat dibezakan Jika anda tidak mahu menambah api/v1 pada beberapa sumber statik dalam perkhidmatan, ia juga tidak dapat dibezakan. Yang berikut menggunakan anotasi tersuai untuk menambahkan awalan URL tertentu secara seragam. satu,

Bahagian 1: Langkah Penyelesaian Masalah Awal Menyemak Status Sistem Apple: Sebelum menyelidiki penyelesaian yang rumit, mari kita mulakan dengan asas. Masalahnya mungkin tidak terletak pada peranti anda; Lawati halaman Status Sistem Apple untuk melihat sama ada AppStore berfungsi dengan betul. Jika terdapat masalah, anda hanya boleh menunggu Apple membetulkannya. Semak sambungan Internet anda: Pastikan anda mempunyai sambungan internet yang stabil kerana isu "Tidak dapat menyambung ke AppStore" kadangkala boleh dikaitkan dengan sambungan yang lemah. Cuba tukar antara Wi-Fi dan data mudah alih atau tetapkan semula tetapan rangkaian (Umum > Tetapkan Semula > Tetapkan Semula Tetapan Rangkaian > Tetapan). Kemas kini versi iOS anda:

Selepas masalah berlaku dalam banyak bursa berpusat, semakin ramai pelabur mata wang mula memindahkan aset ke dompet sejuk untuk mengurangkan risiko yang ditimbulkan oleh pertukaran berpusat. Artikel ini akan memperkenalkan Trezor, penyedia dompet sejuk terawal di dunia Sejak dompet sejuk pertama dilancarkan pada 2014, ia telah dijual di banyak negara di seluruh dunia. Produk Trezor termasuk Model One yang dilancarkan pada 2014 dan versi lanjutan Model T yang dilancarkan pada 2018. Berikut akan terus memperkenalkan perbezaan antara kedua-dua produk ini dan dompet sejuk yang lain. Apakah dompet sejuk Trezor? Pada 2014, Trezor melancarkan dompet sejuk pertama ModelOne. Sebagai tambahan kepada BTC biasa, ETH, USDT dan mata wang lain, dompet itu juga menyokong lebih daripada 1,000 mata wang lain.

php提交表单通过后,弹出的对话框怎样在当前页弹出php提交表单通过后,弹出的对话框怎样在当前页弹出而不是在空白页弹出?想实现这样的效果:而不是空白页弹出:------解决方案--------------------如果你的验证用PHP在后端,那么就用Ajax;仅供参考:HTML code
