Model View Controller(MVC) in PHP

本文介绍MVC模式的基本概念,通过一个简单的PHP实现示例详细解释了Model、View和Controller各部分的功能及其交互流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

The model view controller pattern is the most used pattern for today’s world web applications. It has been used for the first time in Smalltalk and then adopted and popularized by Java. At present there are more than a dozen PHP web frameworks based on MVC pattern.

Despite the fact that the MVC pattern is very popular in PHP, is hard to find a proper tutorial accompanied by a simple source code example. That is the purpose of this tutorial.

  • The MVC pattern separates an application in 3 modules: Model, View and Controller:

  • The model is responsible to manage the data; it stores and retrieves entities used by an application, usually from a database, and contains the logic implemented by the application.
  • The view (presentation) is responsible to display the data provided by the model in a specific format. It has a similar usage with the template modules present in some popular web applications, like wordpress, joomla, …
  • The controller handles the model and view layers to work together. The controller receives a request from the client, invoke the model to perform the requested operations and send the data to the View. The view format the data to be presented to the user, in a web application as an html output. 

The above figure contains the MVC Collaboration Diagram, where the links and dependencies between figures can be observed:
mvc-collaboration

Our short php example has a simple structure, putting each MVC module in one folder:
mvc-structure

Controller

The controller is the first thing which takes a request, parse it, initialize and invoke the model and takes the model response and send it to the presentation layer. It’s practically the liant between the Model and the View, a small framework where Model and View are plugged in. In our naive php implementation the controller is implemented by only one class, named unexpectedly controller. The application entry point will be index.php. The index php file will delegate all the requests to the controller:

  1. // index.php file 
  2. include_once("controller/Controller.php"); 
  3.  
  4. $controller = new Controller(); 
  5. $controller->invoke(); 
	// index.php file
	include_once("controller/Controller.php");

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

Our Controller class has only one function and the constructor. The constructor instantiate a model class and when a request is done, the controller decide which data is required from the model. Then it calls the model class to retrieve the data. After that it calls the corresponding passing the data coming from the model. The code is extremely simple. Note that the controller does not know anything about the database or about how the page is generated.

  1. include_once("model/Model.php"); 
  2.  
  3. class Controller { 
  4.      public $model;  
  5.  
  6.      public function __construct() 
  7.      { 
  8.           $this->model = new Model(); 
  9.      }  
  10.  
  11.      public function invoke() 
  12.      { 
  13.           if (!isset($_GET['book'])) 
  14.           { 
  15.                // no special book is requested, we'll show a list of all available books 
  16.                $books = $this->model->getBookList(); 
  17.                include 'view/booklist.php';
  18.           }
  19.           else
  20.           {
  21.                // show the requested book
  22.                $book = $this->model->getBook($_GET['book']);
  23.                include 'view/viewbook.php'; 
  24.           } 
  25.      } 
include_once("model/Model.php");

class Controller {
     public $model;	

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

     public function invoke()
     {
          if (!isset($_GET['book']))
          {
               // no special book is requested, we'll show a list of all available books
               $books = $this->model->getBookList();
               include 'view/booklist.php';
          }
          else
          {
               // show the requested book
               $book = $this->model->getBook($_GET['book']);
               include 'view/viewbook.php';
          }
     }
}

In the following MVC Sequence Diagram it can be observed the flow during a http request:
mvc-sequence1

Model and Entity Classes

  • The Model represents the data and the logic of an application, what many calls business logic. Usually, it’s responsible for:

  • storing, deleting, updating the application data. Generally it includes the database operations, but implementing the same operations invoking external web services or APIs is not an unusual at all.
  • encapsulating the application logic. This is the layer that should implement all the logic of the application. The most common mistakes are to implement application logic operations inside the controller or the view(presentation) layer.

In our example the model is represented by 2 classes: the “Model” class and a “Book” class. The model doesn’t need any other presentation. The “Book” class is an entity class. This class should be exposed to the View layer and represents the format exported by the Model view. In a good implementation of the MVC pattern only entity classes should be exposed by the model and they should not encapsulate any business logic. Their solely purpose is to keep data. Depending on implementation Entity objects can be replaced by xml or json chunk of data. In the above snippet you can notice how Model is returning a specific book, or a list of all available books:

  1. include_once("model/Book.php"); 
  2.  
  3. class Model { 
  4.     public function getBookList() 
  5.     { 
  6.         // here goes some hardcoded values to simulate the database 
  7.         return array
  8.             "Jungle Book" => new Book("Jungle Book", "R. Kipling", "A classic book."), 
  9.             "Moonwalker" => new Book("Moonwalker", "J. Walker", ""), 
  10.             "PHP for Dummies" => new Book("PHP for Dummies", "Some Smart Guy", ""
  11.         ); 
  12.     } 
  13.  
  14.     public function getBook($title
  15.     { 
  16.         // we use the previous function to get all the books and then we return the requested one. 
  17.         // in a real life scenario this will be done through a db select command 
  18.         $allBooks = $this->getBookList(); 
  19.         return $allBooks[$title]; 
  20.     } 
  21.  
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];
	}

}

In our example the model layer includes the Book class. In a real scenario, the model will include all the entities and the classes to persist data into the database, and the classes encapsulating the business logic.

  1. class Book { 
  2.     public $title
  3.     public $author
  4.     public $description
  5.  
  6.     public function __construct($title, $author, $description
  7.     { 
  8.         $this->title = $title
  9.         $this->author = $author
  10.         $this->description = $description
  11.     } 
class Book {
	public $title;
	public $author;
	public $description;

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

View (Presentation)

The view(presentation layer)is responsible for formating the data received from the model in a form accessible to the user. The data can come in different formats from the model: simple objects( sometimes called Value Objects), xml structures, json, …

The view should not be confused to the template mechanism sometimes they work in the same manner  and address similar issues. Both will reduce the dependency of the presentation layer of from rest of the system and separates the presentation elements(html) from the code. The controller delegate the data from the model to a specific view element, usually associated to the main entity in the model. For example the operation “display account” will be associated to a “display account” view. The view layer can use a template system to render the html pages. The template mechanism can reuse specific parts of the page: header, menus, footer, lists and tables, …. Speaking in the context of the MVC pattern

In our example the view contains only 2 files one for displaying one book and the other one for displaying a list of books.

viewbook.php

  1. <html> 
  2. <head></head> 
  3.  
  4. <body> 
  5.  
  6.     <?php  
  7.  
  8.         echo 'Title:' . $book->title . '<br/>'; 
  9.         echo 'Author:' . $book->author . '<br/>'; 
  10.         echo 'Description:' . $book->description . '<br/>'; 
  11.  
  12.     ?> 
  13.  
  14. </body> 
  15. </html> 
<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. <html> 
  2. <head></head> 
  3.  
  4. <body> 
  5.  
  6.     <table> 
  7.         <tbody><tr><td>Title</td><td>Author</td><td>Description</td></tr></tbody> 
  8.         <?php  
  9.  
  10.             foreach ($books as $title => $book) 
  11.             { 
  12.                 echo '<tr><td><a href="index.php?book='.$book->title.'">'.$book->title.'</a></td><td>'.$book->author.'</td><td>'.$book->description.'</td></tr>'; 
  13.             } 
  14.  
  15.         ?> 
  16.     </table> 
  17.  
  18. </body> 
  19. </html> 
<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>

The above example is a simplified implementation in PHP. Most of the PHP web frameworks based on MVC have similar implementations, in a much better shape. However, the possibility of MVC pattern are endless. For example different layers can be implemented in different languages or distributed on different machines. AJAX applications can implements the View layer directly in Javascript in the browser, invoking JSON services. The controller can be partially implemented on client, partially on server…

  • This post should not be ended before enumerating the advantages of Model View Controller pattern:

  • the Model and View are separated, making the application more flexible.
  • the Model and view can be changed separately, or replaced. For example a web application can be transformed in a smart client application just by writing a new View module, or an application can use web services in the backend instead of a database, just replacing the model module.
  • each module can be tested and debugged separately. 

The files are available for download as a zip from http://sourceforge.net/projects/mvc-php/files/mvc.zip/download

资源下载链接为: https://pan.quark.cn/s/d9ef5828b597 在本文中,我们将探讨如何通过 Vue.js 实现一个带有动画效果的“回到顶部”功能。Vue.js 是一款用于构建用户界面的流行 JavaScript 框架,其组件化和响应式设计让实现这种交互功能变得十分便捷。 首先,我们来分析 HTML 代码。在这个示例中,存在一个 ID 为 back-to-top 的 div 元素,其中包含两个 span 标签,分别显示“回到”和“顶部”文字。该 div 元素绑定了 Vue.js 的 @click 事件处理器 backToTop,用于处理点击事件,同时还绑定了 v-show 指令来控制按钮的显示与隐藏。v-cloak 指令的作用是在 Vue 实例渲染完成之前隐藏该元素,避免出现闪烁现象。 CSS 部分(backTop.css)主要负责样式设计。它首先清除了一些默认的边距和填充,对 html 和 body 进行了全屏布局,并设置了相对定位。.back-to-top 类则定义了“回到顶部”按钮的样式,包括其位置、圆角、阴影、填充以及悬停时背景颜色的变化。此外,与 v-cloak 相关的 CSS 确保在 Vue 实例加载过程中隐藏该元素。每个 .page 类代表一个页面,每个页面的高度设置为 400px,用于模拟多页面的滚动效果。 接下来是 JavaScript 部分(backTop.js)。在这里,我们创建了一个 Vue 实例。实例的 el 属性指定 Vue 将挂载到的 DOM 元素(#back-to-top)。data 对象中包含三个属性:backTopShow 用于控制按钮的显示状态;backTopAllow 用于防止用户快速连续点击;backSeconds 定义了回到顶部所需的时间;showPx 则规定了滚动多少像素后显示“回到顶部”按钮。 在 V
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值