文章目录
  1. 1. Controller 层
  2. 2. Model 和 Entity 类
  3. 3. View层
    1. 3.1. viewbook.php
    2. 3.2. booklist.php
  4. 4. 总结

尽管MVC(model view controller pattern)模式在PHPweb开发中很受欢迎,但是网上很难找到一套代码简单又能清楚阐述PHP MVC模式的案例,本文希望通过理论和代码实践简单阐述PHP MVC模式。

MVC模式在应用中分为Model, ViewController三模块:

Model负责处理数据; 主要负责数据有关的业务处理及存储读取工作。

View负责将Model层的数据按一定的格式样式展现给用户。

Controller负责将Model层和View层联系起来,Controller层响应用户的请求,并将请求业务分发给Model层相应的业务逻辑处理,然后将处理数据再返回给View层展示。

MVC三者之间的关系如图所示:


MVC pattern Diagram

本文设计的MVCdemo目录如下


mvc structure

Controller 层

Controller层可是MVC的入口,接收一个用户请求,解析请求发送给Model层,调用Model层处理业务,接收Model层返回的数据结果,并将数据发送给展示层。Controller层是Model层和View层之间的连接纽带;小的框架中Model层和View层是包含在Controller层中。应用程序中一般会以index.php作为程序的入口,index.php会将用户的所有请求直接转发到Controller层,由Controller层进行相应的处理。

1
2
3
4
5
//index.php file 
include_once("controller/Controller.php");

$controller = new Controller();
$controller->invoke();

在本例中Controller层只有一个函数和一个构造函数。构造函数示例化一个Model类的实例;当Controller对接收的req解析之后,需要决定调用Model层相应的业务逻辑进行处理,然后将Model层返回的处理数据分发给view层展示。需要知道的是Controller层不是知道data如何处理的,也不知道页面是如何生成的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//controller/Controller.php file
include_once("model/Model.php")

class Controller {
public $model;

public function __construct(){
$this->model = new Model();
}

public function invoke() {
if(!isset(!_GET['book'])){
$books = $this->model->getBookList();
include 'view/booklist.php';
}else {
// show the requested book
$book = $this->model->getBook($_GET['book']);
include 'view/viewbook.php';
}
}
}

MVC时序图


MVC Sequence Diagram

Model 和 Entity 类

Model层表示应用程序中的数据和逻辑,通常称之为业务逻辑; 通常表示为如下:

  • 存储,删除, 更新应用程序的数据。通常包括数据库方面的操作, 也可以按照一定的协议格式封装数据然后再通过调用第三方web服务或APIs进行相应的数据处理。

  • 封装应用程序的业务逻辑;实现应用程序的所有业务逻辑。通常人们会错误的应用程序的一些业务逻辑实现写入到Controller层或View层中, 这是一种错误的或者说不规范的做法。

本例中,Model层主要由Model类和Book类组成。Book类是一个实体类,应该暴露给View层。在一个好的MVC模式设计中,Model层中只有Entity类应该暴露接口供View层调用。这样做的唯一目的就是保持数据,因为Entity类中的对象可以通过xmljson数据块替换。在上述的示例中,Model层返回了一个具体的book实例信息,或者一个bookslist:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//model/Model.php file
include_once("model/Book.php");

class Model{
public function getBookList() {
//here goes some hardcoded values to simulate the database
return array(
"Jungle Book"=> new Book("Jungle Book", "R.Kipling", "A classic book."),
"Moonwalker"=> new Book("Moonwalker", "J.Walker",""),
"PHP for Dummies"=> new Book("PHP for Dummies", "Some Smart Guy","")
);
}

public function getBook($title) {
// we use the previous function to get all the books and then we return the requested one.
// in a real life scenario this will be done through a db select command.
$allBooks = $this->getBookList();
return $allBooks[$title];
}
}

在真实场景中,Model层负责将所有的实体和类中的数据持久化到数据库,Model层中的类封装所有的业务逻辑。

1
2
3
4
5
6
7
8
9
10
11
12
//model/Book.php file
class Book {
public $title;
public $author;
public $description;

public function __construct($title, $author, $description){
$this->title = $title;
$this->author = $author;
$this->description = $description;
}
}

View层

View层负责将Model层返回的数据按照一定样式格式化呈现给用户。Model层返回的数据可以是简单的对象类型,也可以是xml, json等复杂的数据类型。

View层对于类似的展示逻辑应提取为模板,便于复用View层代码的同时有利于维护 。Controller层通常通过Entity类中的主Entity实例对象将Model层返回的数据转发给View层中特定的展示元素。

在本例中View层包含展示单个book信息和展示所有book信息两个文件

viewbook.php

1
2
3
4
5
6
7
8
9
10
<html>
<head></head>
<body>
<?php
echo 'Title:' . $book->title . '<br/>';
echo 'Author:' . $book->author . '<br/>';
echo 'Description:' . $book->description . '<br/>';
?>
</body>
</html>

booklist.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<html>
<head></head>
<body>
<table>
<tbody><tr><td>Title</td><td>Author</td><td>Description</td></tr></tbody>
<?php

foreach($books as $title => $book){
echo '<tr><td><a href="index.php?book="' . $book->title .'">'.$book->title .'</a></td><td>'.$book->author.'</td><td>'.$book->description.'</td></tr>';
}
?>
</table>
</body>
</html>

至此本demo分析实现完毕,github示例代码

总结

  • Model层和View层分开使得构建应用程序更加容易
  • Model层和View层可以根据项目需要其中一层构成MVCV模式
  • 可以对MVC模式中每个层进行单独的测试和调试

作者署名:朴实的一线攻城狮
本文标题:php中mvc模式使用总结(一)
本文出处:http://researchlab.github.io/2016/07/30/php-mvc-1/
版权声明:本文由Lee Hong创作和发表,采用署名(BY)-非商业性使用(NC)-相同方式共享(SA)国际许可协议进行许可,转载请注明作者及出处, 否则保留追究法律责任的权利。

@一线攻城狮

关注微信公众号 @一线攻城狮

总访问:
总访客: