PHP 中的 MVC(Model-View-Controller)模型是一种软件设计模式,用于构建结构清晰、易于维护的 web 应用程序。MVC 将应用程序划分为三个核心组件,每个组件承担不同的职责:
Model(模型)
职责:
- 表示应用程序的核心数据和业务逻辑。
- 通常与数据库交互,负责数据的查询、创建、更新和删除(CRUD)操作。
- 可能包含实体类(对应数据库表)、数据访问对象(DAO)、数据映射器(ORM)或服务类等,处理与应用程序数据相关的所有事务。
示例:
// 假设有一个简单的用户模型
namespace Blog\Model;
class User
{
private $id;
private $username;
private $email;
private $password;
public function __construct(int $id, string $username, string $email, string $password)
{
$this->id = $id;
$this->username = $username;
$this->email = $email;
$this->password = $password;
}
// 其他属性的getter和setter...
public function save(Database $db): void
{
// 保存用户到数据库的逻辑...
}
}
View(视图)
职责:
- 负责呈现数据给用户,通常以 HTML、JSON、XML 或其他格式输出。
- 视图应当尽可能保持纯净,只包含展示逻辑,避免直接处理业务逻辑或数据操作。
- 可以使用模板引擎(如 Twig、Blade 等)来生成视图,将数据与 HTML 结构分离,提高代码可读性和复用性。
示例:
<!-- views/user/profile.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>User Profile</title>
</head>
<body>
<h1>{{ user.username }}</h1>
<p>Email: {{ user.email }}</p>
</body>
</html>
Controller(控制器)
职责:
- 接收用户的请求(通常是 HTTP 请求)。
- 解析请求参数,调用相应的模型进行数据处理。
- 获得处理结果后,选择合适的视图进行渲染,并将数据传递给视图。
- 处理用户交互,如表单提交、AJAX 请求等,协调模型和视图的工作。
示例:
// controllers/UserController.php
namespace Blog\Controller;
use Blog\Model\User;
use Blog\Model\Database;
class UserController
{
public function profileAction(int $userId, Database $db): void
{
$user = $db->getUserById($userId);
// 使用模板引擎渲染视图
include 'views/user/profile.html';
}
}
工作流程
当用户发起一个请求时,流程如下:
- 请求首先到达 路由器(在某些框架中内置),路由器解析请求URL,确定应该调用哪个控制器的哪个方法。
- 控制器方法被调用,它可能从模型获取数据,也可能处理用户的输入(如表单提交)。
- 控制器将处理后的数据传递给视图,或者指示视图使用特定的数据源(如模型)。
- 视图根据收到的数据生成HTML或其他格式的响应,发送回客户端。
通过 MVC 架构,PHP 应用程序得以实现关注点分离(Separation of Concerns, SoC),即每个组件专注于自己的职责,降低各部分之间的耦合度,提升代码的可读性、可测试性和可维护性。许多 PHP 框架,如 Laravel、Symfony、Yii、CodeIgniter 等,都基于 MVC 或其变体(如 HMVC、MVVM 等)来组织应用程序结构。
要通过实战了解 PHP MVC 模型的实际应用,您可以按照以下步骤创建一个简单但完整的 PHP MVC 应用程序。这里我们将创建一个简易的博客系统,包括文章列表、文章详情、添加新文章和编辑文章的功能。由于篇幅限制,这里仅提供关键代码片段和结构说明,实际开发时请确保遵循良好的编程规范并考虑安全性问题。
目录结构:
blog/
|-- app/
| |-- Controller/
| | |-- ArticleController.php
| |-- Model/
| | |-- Article.php
| |-- View/
| |-- article/
| |-- list.php
| |-- detail.php
| |-- form.php
|-- public/
| |-- index.php
|-- .htaccess
.htaccess (假设使用 Apache 服务器,用于重写规则,将所有请求指向 public/index.php
):
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L]
public/index.php (入口文件,加载框架/自动加载器,处理请求):
<?php
require_once '../app/bootstrap.php';
$router = new Router();
$router->dispatch($_SERVER['REQUEST_URI']);
app/Bootstrap.php (配置环境、设置自动加载、初始化路由等):
<?php
spl_autoload_register(function ($class) {
$class = str_replace('\\', '/', $class);
require_once '../app/' . $class . '.php';
});
$router = new Router();
$router->addRoute('GET', '/', ['ArticleController', 'listAction']);
$router->addRoute('GET', '/article/{id:\d+}', ['ArticleController', 'detailAction']);
$router->addRoute('GET', '/new-article', ['ArticleController', 'createFormAction']);
$router->addRoute('POST', '/save-article', ['ArticleController', 'saveAction']);
app/Controller/ArticleController.php:
<?php
class ArticleController
{
public static function listAction()
{
$articles = Article::getAll();
include '../view/article/list.php';
}
public static function detailAction($id)
{
$article = Article::getById($id);
include '../view/article/detail.php';
}
public static function createFormAction()
{
include '../view/article/form.php';
}
public static function saveAction()
{
// 获取 POST 数据,验证并保存到数据库
$articleData = $_POST; // 实际开发中请使用过滤和验证库
$article = new Article($articleData);
$article->save();
// 保存成功后跳转到详情页
header('Location: /article/' . $article->getId());
exit;
}
}
app/Model/Article.php:
<?php
class Article
{
private $id;
private $title;
private $content;
public function __construct(array $data)
{
$this->title = $data['title'];
$this->content = $data['content'];
}
// 其他属性的 getter 和 setter...
public static function getAll()
{
// 查询数据库,获取所有文章(实际开发中请使用数据库连接库)
$articles = []; // 示例数据
return $articles;
}
public static function getById($id)
{
// 查询数据库,获取指定 ID 的文章(实际开发中请使用数据库连接库)
$article = []; // 示例数据
return $article;
}
public function save()
{
// 保存文章到数据库(实际开发中请使用数据库连接库)
}
}
app/View/article/list.php, app/View/article/detail.php, app/View/article/form.php:
分别编写显示文章列表、文章详情和文章创建表单的 HTML 页面。在这些页面中,可以使用 PHP 变量来动态渲染数据。例如,在 list.php
中使用循环遍历 $articles
并输出每一项。
以上代码示例仅作为学习 PHP MVC 架构的一个简单起点,实际项目中需要考虑更多细节,如错误处理、用户身份验证、数据库连接管理、模板引擎使用、前端交互(如 AJAX)等。建议使用成熟的 PHP 框架(如 Laravel、Symfony、Yii 等)来快速搭建 MVC 应用程序,并利用它们提供的各种工具和最佳实践来提高开发效率和代码质量。