#自己手写一个简易的MVC框架 mvc结构分为: m(model) - v(view) - c(controller). 其中m和v可用第三方包实现,而c这需要自己实现(原因: c是业务逻辑实现区,充满了不确定性).
m用到的第三方库为: catfan/medoo
v用到的第三方库为: league/plates
具体实现步骤步骤
-
创建一个项目目录
testFrame在此目录下分别创建application和core目录 -
安装第三方包
- 安装catfan/medoo:
composer require catfan/medoo - 安装league/plates:
composer require league/plates - 最终目录结构
- 安装catfan/medoo:
-
在core目录中新建Model和View脚本并在其中导入第三方包
- Model.php的代码:
<?php namespace core; use Medoo\Medoo; class Model extends Medoo { public function __construct(array $options) { parent::__construct($options); } }- View.php的代码:
<?php namespace core; use League\Plates\Engine; class View extends Engine { public function __construct($directory = null, $fileExtension = 'php') { parent::__construct($directory, $fileExtension); } }3.最终目录
-
在
application目录下创建三个目录,分别是models, views, controllers- 在
models目录下新建StaffsModel.php,获取员工表的数据. - 在
views目录下新建staffs目录,创建显示员工数据的视图list.php(html). - 在
controllers目录下创建StaffsController.php,把员工数据(StaffsModel)插入到视图(StaffsView)中.
具体代码:
StaffsController.php
<?php namespace controllers; use Closure; // 服务容器 class Container { protected $instanles; // 插入外部依赖 public function bind($alias, Closure $process) { $this->instanles[$alias] = $process; } // 取出外部依赖 public function make($alias, $params = []):object { return call_user_func_array($this->instanles[$alias], $params); } } // 门面 class Facade { protected static $container = null; // 构造函数,初始化$container public static function initialize(Container $container) { static::$container = $container; } } // 静态化模型类 class StaticStaffModel extends Facade { public static function select($tablename, $field, $condition) { return static::$container->make('model')->select($tablename, $field, $condition); } } // 静态化视图类 class StaticStaffView extends Facade { public static function fetch($path, $data) { return static::$container->make('view')->render($path, ['staffs' => $data]); } } // 控制器 class StaffController { public function __construct(Container $container) { Facade::initialize($container); } public function index($tablename, $field, $condition, $path) { $data = StaticStaffModel::select($tablename, $field, $condition); return StaticStaffView::fetch($path, $data); } }StaffsModel.php
<?php namespace models; use testFrame\core\Model; class StaffModel extends Model { public function __construct(array $options) { parent::__construct($options); } }staffs/list.php
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>员工信息</title> <style> body { display: flex; flex-direction: column; align-items: center; } table { border-collapse: collapse; border: 1px solid; width: 50%; text-align: center; } th, td { border: 1px solid; padding: 5px; } tr:first-child { background-color: #eee; } </style> </head> <body> <h3>用户管理系统</h3> <table> <tr> <th>id</th> <th>姓名</th> <th>性别</th> <th>工资</th> <th>邮箱</th> <th>操作</th> </tr> <?php foreach ($staffs as $staff): ?> <tr> <td><?= $this->e($staff['sid']) ?></td> <td><?= $this->e($staff['name']) ?></td> <td><?= $this->e($staff['gender']) == 'male' ? '男' : '女' ?></td> <td><?= $this->e($staff['salary']) ?></td> <td><?= $this->e($staff['email']) ?></td> <td> <button>编辑</button> <button>删除</button> </td> </tr> <?php endforeach ?> </table> <p> <a href="">1</a> <a href="">2</a> <a href="">3</a> <a href="">4</a> <a href="">5</a> <a href="">6</a> </p> </body> </html> - 在
5. 在`composer.json`中添加*autoload*,然后在控制台执行`composer dump`.注意,控制台路径要在当前目录下.
```json5
{
"name": "zhang/null",
"description": "this is a test",
"require": {
"catfan/medoo": "^1.7",
"league/plates": "^3.4"
},
"autoload": {
"classmap": [
"application/controllers",
"application/models",
"application/views",
"core"
]
}
}
- 测试,在根目录下创建一个
index.php进行测试,具体代码如下:
<?php
use testFrame\core\View;
use models\StaffModel;
use controllers\Container;
use controllers\StaffController;
require_once './vendor/autoload.php';
$container = new Container();
$container->bind('view', function () { return new View('application/views'); });
$container->bind(
'model', function () {
$config = [
'database_type' => 'mysql',
'database_name' => 'phpedu',
'server' => 'localhost',
'username' => 'admin',
'password' => '123456',
];
return new StaffModel($config);
}
);
$controller = new StaffController($container);
echo $controller->index('staffs', ['sid', 'name', 'age', 'gender', 'salary', 'birthday'], ['LIMIT' => [20, 10]], 'staffs/list');
效果:
)