基于composer的MVC小框架实例
程序员文章站
2022-03-24 21:17:16
...
composer框架介绍
1. 架构
- M: Model, 模型, 使用第三方组件来实现它
- V: View, 视图, 使用第三方组件来实现它
- C: Controller, 控制器, 我们的业务逻辑全部写到控制器中
2. 第三方包
- Model:
composer require catfan/medoo
- View:
composer require league/plates
3. 目录
- app 目录: 用户应用,按 mvc 框架创建
- core 目录: 框架的核心代码,创建自己的模型类与视图类
- vendor 目录:composer与第三方组件存储目录
4.流程
- 在项目目录下使用composer命令进行组件的安装
- 在核心core目录创建MVC文件,去继承第三方组件,然后编写公用的方法或属性给用户应用的MVC文件使用
- APP目录是用户应用的MVC文件,分别创建文件夹进行存放,里面的MVC文件继承核心的MVC文件,进行实际的用户应用代码编写/组件的实际调用
- 创建好文件和命名空间后在composer.json文件中autoload进行PSR-4加载
- 编写入口文件,引入composer的自动加载,进行路由访问
- 我的方式是将model文件直接引入到controller文件中使用,需要使用到什么model就引入什么model,核心的view直接给核心的controller引入实例化赋值到属性$view中存储起来使用,用户应用控制器都需要视图调用,而且视图类文件只有一个,只需传入参数即可
目录图片:
组件的具体使用查看组件的介绍文档,以下部分是core目录
的代码:
Controller.php
<?php
namespace core;
use core\View;
// 自定义核心控制器
abstract class Controller
{
// 每一个控制器都需要调用到视图组件,实例化存储到属性view中
protected $view = '';
// 构造函数,进行视图类的实例赋值到属性view
public function __construct()
{
$this->view = new View('app/views');
}
}
Model.php
<?php
// 模型类
namespace core;
// 模型类继承自 组件Medoo
use Medoo\Medoo;
abstract class Model extends Medoo
{
public function __construct()
{
$optinos = [
'database_type' => 'mysql',
'database_name' => 'phpedu',
'server' => 'localhost',
'username' => 'root',
'password' => 'root',
];
parent::__construct($optinos);
}
}
View.php
<?php
// 视图类
namespace core;
// 视图类继承自 plates组件
use League\Plates\Engine;
class View extends Engine
{ public $templates = null;
public function __construct($path)
{
$this->templates = parent::__construct($path);
}
}
以下是app目录
用户应用:controllers/UsersController.php
<?php
namespace controllers;
use core\Controller;
use models\UsersModel;
// 继承核心controller
class UsersController extends Controller
{
public function __construct()
{
// 可以不写,但最好调用一下父类的构造方法
parent::__construct();
}
// 首页展示方法
public function index()
{
$model = new UsersModel();
$users = $model ->select('users',['id','name','email'],['id[>]'=>20,'LIMIT'=>5]);
return $this->view->render('users/list',['users'=>$users]);
}
// 删除数据方法
public function delete()
{
$id = $_GET['id'];
$model = new UsersModel();
$result = $model->delete("users", [
"id" => $id
]);
// return __METHOD__;
return $result->rowCount();;
}
// 展示修改页面
public function edit()
{
$id = $_GET['id'];
$model = new UsersModel();
$user = $model->get("users", ['id','name','email'], [
"id" => $id
]);
return $this->view->render('users/edit',['user'=>$user]);
// return print_r($_GET,true);
}
// 更新数据方法
public function update()
{
$id = $_GET['id'];
$model = new UsersModel();
$data = $model->update("users", [
"name" => $_POST['name'],
"email" =>$_POST['email']
], [
"id" => $id
]);
return $data->rowCount();
// return print_r($_POST,true);
}
}
models/UsersModel.php
<?php
namespace models;
use core\Model;
// 继承核心的Model
class UsersModel extends Model
{
public function __construct()
{
parent::__construct();
}
// 自行创建model组件中没有的方法/定制式的方法
public function idGetDate()
{
return '自定义模型数据处理';
}
}
Views
文件夹主要存放的是视图文件,查看组件文档有几点重点:
- 视图/模板文件通常会与控制器中的一个方法对应
- 根据控制器不同,创建不同的目录来存放这些视图/模板文件
- 视图下面的目录与控制器对应
- 视图下面的控制器对应的目录下面是与控制器方法对应的模板文件
users/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>
</tr>
<?php foreach ($users as $user): ?>
<tr>
<!-- $this->e:模板引擎Plates中的一个函数,用来过滤特殊字符 -->
<td><?=$user['id']?></td>
<td><?=$this->e($user['name'])?></td>
<td><?=$this->e($user['email'])?></td>
<td><button onclick="location.href='/mvc/index.php/users/edit.html?id=<?=$user['id']?>'" >编辑</button>
<button onclick="del(<?=$user['id']?>)">删除</button></td>
</tr>
<?php endforeach ?>
</table>
<p>
<a href="">假分页</a>
<a href="">1</a>
<a href="">2</a>
<a href="">3</a>
<a href="">4</a>
</p>
</body>
<script>
function del(id){
let url = '/mvc/index.php/users/delete.html?id='+id;
return confirm('是否删除?') ?location.href=url : false;
}
</script>
</html>
users/edit.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>用户编辑页</title>
</head>
<body>
<form action="/mvc/index.php/users/update.html?id=<?=$this->e($user['id'])?>" method="POST" >
<fieldset>
<legend>用户编辑</legend>
<p>
<label for="">用户名:</label>
<input type="text" name="name" id="name" value="<?=$this->e($user['name'])?>" >
</p>
<p>
<label for="">邮箱:</label>
<input type="email" name="email" id="email" value="<?=$this->e($user['email'])?>">
</p>
<p>
<button>保存</button>
</p>
</fieldset>
</form>
</body>
</html>
创建入口文件index.php
<?php
//加载composer的自动加载文件
require __DIR__ . '/vendor/autoload.php';
// 路由访问拦截
$pathinfo = array_values(array_filter(explode('/', str_replace('.html','',$_SERVER['PATH_INFO']))));
// 如果要用路由拦截访问,不能使用USE进行文件别名,
$controller = '\\controllers\\' . ucfirst(array_shift($pathinfo)) . 'Controller';
$action = array_shift($pathinfo);
// 测试
// echo $controller.'-'.$action;
// printf('<pre>%s</pre>', print_r($pathinfo, true));
$params = [];
// 每次处理的是二个元素,所以$i = $i + 2
for ($i=0; $i < count($pathinfo); $i+=2) {
// $pathinfo中前一个元素是新数组中的键名, 后面一个是它的值
if (isset($pathinfo[$i + 1])) {
$params[$pathinfo[$i]] = $pathinfo[$i + 1];
}
}
echo call_user_func_array([(new $controller), $action], $params );
上一篇: 前端编码风格规范之 HTML 规范
下一篇: 怎么调用php中的数组
推荐阅读
-
用 Composer构建自己的 PHP 框架之设计 MVC,composermvc_PHP教程
-
基于Python的接口测试框架实例
-
用 Composer构建自己的 PHP 框架之基础准备_php实例
-
基于thinkPHP框架实现留言板的方法_php实例
-
php实现最简单的MVC框架实例教程,mvc框架实例教程
-
手把手编写自己的 PHP MVC 框架实例教程 mvc php 案例 php mvc教程 php mvc开发实
-
实现JavaScript MVC样式框架的简单代码实例
-
基于CI框架的微信网页授权库示例_php实例
-
基于MVC4+EasyUI的Web开发框架经验总结(4)--使用图表控件Highcharts
-
php实现简单的MVC框架实例_PHP