博客列表 >PHP: 一个迷你的MVC小框架

PHP: 一个迷你的MVC小框架

zl的php学习博客
zl的php学习博客原创
2021年03月05日 17:29:45781浏览

自己手写一个简易的MVC框架

  1. mvc结构分为: m(model) - v(view) - c(controller).
  2. 其中mv可用第三方包实现,而c这需要自己实现(原因: c是业务逻辑实现区,充满了不确定性).
  3. m用到的第三方库为: catfan/medoo
  4. v用到的第三方库为: league/plates

具体实现步骤步骤

  1. 创建一个项目目录testFrame在此目录下分别创建applicationcore目录
  2. 安装第三方包
    1. 安装catfan/medoo: composer require catfan/medoo
      安装catfan-medoo
    2. 安装league/plates: composer require league/plates
      安装league-plates
    3. 最终目录结构
      最终目录结构
  3. 在core目录中新建Model和View脚本并在其中导入第三方包
    1. Model.php的代码:
      1. <?php
      2. namespace core;
      3. use Medoo\Medoo;
      4. class Model extends Medoo
      5. {
      6. public function __construct(array $options)
      7. {
      8. parent::__construct($options);
      9. }
      10. }
    2. View.php的代码:
      1. <?php
      2. namespace core;
      3. use League\Plates\Engine;
      4. class View extends Engine
      5. {
      6. public function __construct($directory = null, $fileExtension = 'php') { parent::__construct($directory, $fileExtension); }
      7. }
      3.最终目录
      引入第三方包
  4. application目录下创建三个目录,分别是models, views, controllers

    1. models目录下新建StaffsModel.php,获取员工表的数据.
    2. views目录下新建staffs目录,创建显示员工数据的视图list.php(html).
    3. controllers目录下创建StaffsController.php,把员工数据(StaffsModel)插入到视图(StaffsView)中.

    具体代码:

    StaffsController.php
    ```phpt

    1. <?php
    1. namespace controllers;
    2. use Closure;
    3. // 服务容器
    4. class Container
    5. {
    6. protected $instanles;
    7. // 插入外部依赖
    8. public function bind($alias, Closure $process)
    9. {
    10. $this->instanles[$alias] = $process;
    11. }
    12. // 取出外部依赖
    13. public function make($alias, $params = []):object
    14. {
    15. return call_user_func_array($this->instanles[$alias], $params);
    16. }
    17. }
    18. // 门面
    19. class Facade
    20. {
    21. protected static $container = null;
    22. // 构造函数,初始化$container
    23. public static function initialize(Container $container)
    24. {
    25. static::$container = $container;
    26. }
    27. }
    28. // 静态化模型类
    29. class StaticStaffModel extends Facade
    30. {
    31. public static function select($tablename, $field, $condition)
    32. {
    33. return static::$container->make('model')->select($tablename, $field, $condition);
    34. }
    35. }
    36. // 静态化视图类
    37. class StaticStaffView extends Facade
    38. {
    39. public static function fetch($path, $data)
    40. {
    41. return static::$container->make('view')->render($path, ['staffs' => $data]);
    42. }
    43. }
    44. // 控制器
    45. class StaffController
    46. {
    47. public function __construct(Container $container)
    48. {
    49. Facade::initialize($container);
    50. }
    51. public function index($tablename, $field, $condition, $path)
    52. {
    53. $data = StaticStaffModel::select($tablename, $field, $condition);
    54. return StaticStaffView::fetch($path, $data);
    55. }
    56. }
    1. > StaffsModel.php
    2. ```phpt
    3. <?php
    4. namespace models;
    5. use testFrame\core\Model;
    6. class StaffModel extends Model
    7. {
    8. public function __construct(array $options)
    9. {
    10. parent::__construct($options);
    11. }
    12. }

    staffs/list.php
    ```html

    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    6. <title>员工信息</title>
    7. <style>
    8. body {
    9. display: flex;
    10. flex-direction: column;
    11. align-items: center;
    12. }
    13. table {
    14. border-collapse: collapse;
    15. border: 1px solid;
    16. width: 50%;
    17. text-align: center;
    18. }
    19. th,
    20. td {
    21. border: 1px solid;
    22. padding: 5px;
    23. }
    24. tr:first-child {
    25. background-color: #eee;
    26. }
    27. </style>
    28. </head>
    29. <body>
    30. <h3>用户管理系统</h3>
    31. <table>
    32. <tr>
    33. <th>id</th>
    34. <th>姓名</th>
    35. <th>性别</th>
    36. <th>工资</th>
    37. <th>邮箱</th>
    38. <th>操作</th>
    39. </tr>
    40. <?php foreach ($staffs as $staff): ?>
    41. <tr>
    42. <td><?= $this->e($staff['sid']) ?></td>
    43. <td><?= $this->e($staff['name']) ?></td>
    44. <td><?= $this->e($staff['gender']) == 'male' ? '男' : '女' ?></td>
    45. <td><?= $this->e($staff['salary']) ?></td>
    46. <td><?= $this->e($staff['email']) ?></td>
    47. <td>
    48. <button>编辑</button>
    49. <button>删除</button>
    50. </td>
    51. </tr>
    52. <?php endforeach ?>
    53. </table>
    54. <p>
    55. <a href="">1</a>
    56. <a href="">2</a>
    57. <a href="">3</a>
    58. <a href="">4</a>
    59. <a href="">5</a>
    60. <a href="">6</a>
    61. </p>
    62. </body>
    63. </html>
  1. 5. `composer.json`中添加*autoload*,然后在控制台执行`composer dump`.注意,控制台路径要在当前目录下.
  2. ```json5
  3. {
  4. "name": "zhang/null",
  5. "description": "this is a test",
  6. "require": {
  7. "catfan/medoo": "^1.7",
  8. "league/plates": "^3.4"
  9. },
  10. "autoload": {
  11. "classmap": [
  12. "application/controllers",
  13. "application/models",
  14. "application/views",
  15. "core"
  16. ]
  17. }
  18. }
  1. 测试,在根目录下创建一个index.php进行测试,具体代码如下:
  1. <?php
  2. use testFrame\core\View;
  3. use models\StaffModel;
  4. use controllers\Container;
  5. use controllers\StaffController;
  6. require_once './vendor/autoload.php';
  7. $container = new Container();
  8. $container->bind('view', function () { return new View('application/views'); });
  9. $container->bind(
  10. 'model', function () {
  11. $config = [
  12. 'database_type' => 'mysql',
  13. 'database_name' => 'phpedu',
  14. 'server' => 'localhost',
  15. 'username' => 'admin',
  16. 'password' => '123456',
  17. ];
  18. return new StaffModel($config);
  19. }
  20. );
  21. $controller = new StaffController($container);
  22. echo $controller->index('staffs', ['sid', 'name', 'age', 'gender', 'salary', 'birthday'], ['LIMIT' => [20, 10]], 'staffs/list');

效果:
效果)

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议