ASCII码 ASCII码

浅谈PHP-MVC模式及简单实现

发布于:2022-02-24 09:29:58  栏目:技术文档

浅谈PHP-MVC模式及简单实现

何为MVC?

MVC模式(Model–view–controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)。

MVC模式最早由Trygve Reenskaug在1978年提出[1],是施乐帕罗奥多研究中心(Xerox PARC)在20世纪80年代为程序语言Smalltalk发明的一种软件架构。MVC模式的目的是实现一种动态的程序设计,使后续对程序的修改和扩展简化,并且使程序某一部分的重复利用成为可能。除此之外,此模式透过对复杂度的简化,使程序结构更加直观。

模型(Model)

用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法。“ Model ”有对数据直接访问的权力,例如对数据库的访问。“Model”不依赖“View”和“Controller”,也就是说, Model 不关心它会被如何显示或是如何被操作。但是 Model 中数据的变化一般会通过一种刷新机制被公布。为了实现这种机制,那些用于监视此 Model 的 View 必须事先在此 Model 上注册,从而,View 可以了解在数据 Model 上发生的改变。

视图(View)

能够实现数据有目的的显示(理论上,这不是必需的)。在 View 中一般没有程序上的逻辑。为了实现 View 上的刷新功能,View 需要访问它监视的数据模型(Model),因此应该事先在被它监视的数据那里注册。

控制器(Controller)

起到不同层面间的组织作用,用于控制应用程序的流程。它处理事件并作出响应。“事件”包括用户的行为和数据 Model 上的改变。

接下来我们用代码演绎一下

composer.json如下" class="reference-link">首先创建目录mvc,下面创建文件目录mvc,创建composer.json如下

  1. {
  2. "name": "xia/mymvc",
  3. "require": {},
  4. "autoload": {
  5. "psr-4": {
  6. "xia\\app\\": "mvc/"
  7. }
  8. },
  9. "authors": [{
  10. "name": "xia",
  11. "email": "xia@qq.com"
  12. }]
  13. }

composer install(主要是为了获得类的自动加载),创建其它文件,目录结构如下:" class="reference-link">运行composer install(主要是为了获得类的自动加载),创建其它文件,目录结构如下:

Model.php" class="reference-link">Model.php

  1. <?php
  2. // 获取模型数据
  3. namespace xia\app;
  4. use PDO;
  5. class Model
  6. {
  7. public function getData()
  8. {
  9. return (new PDO('mysql:host=localhost;charset=utf8;dbname=phpcn', 'root', '', [PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING]))->query('SELECT `cou_id`,`title`,`pic`,`info`,`add_time`FROM `mj_course_lists` ORDER BY `cou_id` DESC LIMIT 6')->fetchAll();
  10. }
  11. public function editData()
  12. {
  13. }
  14. }

View.php" class="reference-link">View.php

  1. <?php
  2. namespace xia\app;
  3. class View
  4. {
  5. // $data渲染到视图层的数据
  6. public function fetch($data)
  7. {
  8. $table = '<table border="1" cellspacing="0" cellpadding="5" align="center">';
  9. $table .= '<caption>课程信息表</caption>';
  10. $table .= '
  11. <tr align="center">
  12. <td>编号</td>
  13. <td>名称</td>
  14. <td>封面</td>
  15. <td>课程简介</td>
  16. <td>创建时间</td>
  17. <td>操作</td>
  18. </tr>
  19. ';
  20. foreach ($data as $list) {
  21. $table .= '<tr>';
  22. $table .= '<td>' . $list['cou_id'] . '</td>';
  23. $table .= '<td>' . $list['title'] . '</td>';
  24. $table .= "<td><img style='width:100px' src='{$list['pic']}' alt='课程封面' ></td>";
  25. $table .= '<td>' . $list['info'] . '</td>';
  26. $table .= '<td>' . date("Y-m-d H:m:s", $list['add_time']) . '</td>';
  27. $table .= '<td><button>删除</button>&nbsp;<button>编辑</button> </td>';
  28. $table .= '</tr>';
  29. }
  30. $table .= '</table>';
  31. return $table;
  32. }
  33. }

Controller.php" class="reference-link">Controller.php

  1. <?php
  2. namespace xia\app;
  3. // 类的自动加载
  4. require __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';
  5. // 中间层 controller 协调 m v
  6. class Controller
  7. {
  8. protected $container;
  9. // 将外部依赖的对象 model view 在构造器中注入进来 完成外部对象在多个方法中共享
  10. function __construct($container)
  11. {
  12. $this->container = $container;
  13. }
  14. function index()
  15. {
  16. // 获取数据
  17. $data = $this->container->make('model')->getData();
  18. // 渲染数据到视图层
  19. return $this->container->make('view')->fetch($data);
  20. }
  21. function edit()
  22. {
  23. $this->container->make('model')->editData();
  24. }
  25. }
  26. $container = new Container;
  27. // 绑定一个闭包到服务容器中 我们使用$model对象时才去实例化
  28. $container->bind('model', function () {
  29. return new Model;
  30. });
  31. $container->bind('view', function () {
  32. return new View;
  33. });
  34. $c2 = new Controller($container);
  35. echo $c2->index();

依赖注入(dependency injection)

依赖”是指可被方法调用的事物。依赖注入形式下,调用方不再直接使用“依赖”,取而代之是“注入” 。“注入”是指将“依赖”传递给调用方的过程。在“注入”之后,调用方才会调用该“依赖”。

在PHP中,如果当前类所依赖的外部对象过多,名称很长 将依赖的所有外部对象放到一个容器中统一管理,并且还可以起别名

服务容器

服务容器是一个用于管理类依赖和执行依赖注入的工具,是一个自动产生类、对象的工厂。

Container.php" class="reference-link">Container.php

  1. <?php
  2. namespace xia\app;
  3. use Closure;
  4. // 服务容器 一个自动生产类 /对象的工厂
  5. class Container
  6. {
  7. // 对象容器
  8. protected $instances = [];
  9. /**
  10. * 绑定一个类标识、闭包、实例到容器
  11. * @access public
  12. * @param string|array $abstract 类标识或者接口的别名 alias
  13. * @param mixed $concrete 要绑定的类、闭包或者实例
  14. *
  15. */
  16. // 往容器数组中绑定对象
  17. public function bind($abstract, Closure $concrete)
  18. {
  19. $this->instances[$abstract] = $concrete;
  20. }
  21. public function make($abstract, $params = [])
  22. {
  23. return call_user_func_array($this->instances[$abstract], $params);
  24. }
  25. }
相关推荐
阅读 +