MVC
Model.php模型类
<?php
namespace mvc_demo;
// 模型类: 用于数据库操作
class Model
{
//获取数据库方法
public function getData()
{
return (new \PDO('mysql:host=localhost;dbname=phpedu', 'root','root'))
->query('SELECT * FROM `staffs` LIMIT 10')
->fetchAll(\PDO::FETCH_ASSOC);
}
}
View.php 视图
<?php
namespace mvc_demo;
// 视图类
class View
{
//视图方法 显示用户所需数据
public function fetch($data)
{
$table = '<table>';
$table .= '<caption>员工信息表</caption>';
$table .= '<tr><th>ID</th><th>姓名</th><th>性别</th><th>职务</th><th>手机号</th><th>入职时间</th></tr>';
// 将数据循环遍历出来
foreach ($data as $staff) {
$table .= '<tr>';
$table .= '<td>' . $staff['id'] . '</td>';
$table .= '<td>' . $staff['name'] . '</td>';
$table .= '<td>' . ($staff['sex'] ? '男' : '女') . '</td>';
$table .= '<td>' . $staff['position'] . '</td>';
$table .= '<td>' . $staff['mobile'] . '</td>';
$table .= '<td>' . date('Y年m月d日', $staff['hiredate']) . '</td>';
$table .= '</tr>';
}
$table .= '</table>';
return $table;
}
}
//样式
echo '<style>
table {border-collapse: collapse; border: 1px solid;text-align: center; width: 500px;height: 150px;width: 600px;}
caption {font-size: 1.2rem; margin-bottom: 10px;}
tr:first-of-type { background-color:wheat;}
td,th {border: 1px solid; padding:5px}
</style>';
控制器 第一种注入
<?php
namespace mvc_demo;
// 控制器1
// 1. 加载模型类
require 'Model.php';
// 2. 加载视图
require 'View.php';
// 3. 创建控制
class Controller2
{
public function index(Model $model, View $view)
{
// 1. 获取数据
$data = $model->getData();
// 2. 渲染模板/视图
return $view->fetch($data);
}
public function index2(Model $model, View $view)
{
}
}
// 客户端
$model = new Model;
$view = new View;
// 实例化控制器类
$controller = new Controller2;
echo $controller->index($model, $view);
控制器 第二种注入
<?php
namespace mvc_demo;
// 控制器依赖注入点改到构造方法, 实现对外部依赖对象的共享
// 1. 加载模型类
require 'Model.php';
// 2. 加载视图
require 'View.php';
// 3. 创建控制
class Controller3
{
// 依赖对象属性
private $model;
private $view;
// 构造方法
public function __construct(Model $model, View $view)
{
$this->model = $model;
$this->view = $view;
}
public function index()
{
// 1. 获取数据
$data = $this->model->getData();
// 2. 渲染模板/视图
return $this->view->fetch($data);
}
public function index2()
{
// 1. 获取数据
$data = $this->model->getData();
// 2. 渲染模板/视图
return $this->view->fetch($data);
}
}
// 客户端
$model = new Model;
$view = new View;
// 实例化控制器类
$controller = new Controller3($model, $view);
echo $controller->index();
// 当前类中对其它类的实例化都在当前类中完成, 造成代码间中的耦合度过高, 过分依赖外部对象
// 使用依赖注入的方式
2.分页
首页文件index.php
<?php
// 连接数据库
require 'connect.php';
// 1. 当前的页数/页码
$page = $_GET['p'] ?? 1;
// 2. 每页显示的记录数量
$num = 5;
// 3. 总页数
$sql = "SELECT CEIL(COUNT(`id`)/{$num}) AS `total` FROM `jizhang`";
$pages = $pdo->query($sql)->fetch()['total'];
// 4. 偏移量
$offset = $num * ($page - 1);
// 5. 分页数据
$sql = "SELECT * FROM `jizhang` LIMIT {$num} OFFSET {$offset}";
$staffs = $pdo->query($sql)->fetchAll();
// print_r($staffs);
// 超过总页数提示
$err = "<script>alert('页码超出总页码');location.href='demo4.php';</script>";
//当前页码
$page = $_GET['p'] ?? 1 ;
if ($page>$pages){
die($err);
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>分页数据展示</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<table>
<caption>消费明细表</caption>
<thead>
<tr>
<th>ID</th>
<th>金额</th>
<th>账户</th>
<th>成员</th>
<th>备注</th>
<th>用户id</th>
<th>入职时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<?php foreach ($staffs as $staff) : ?>
<tr>
<td><?php echo $staff['id'] ?></td>
<td><?php echo $staff['jine'] ?></td>
<td><?php echo $staff['zhanghu'] ?></td>
<td><?php echo $staff['chengyuan'] ?></td>
<td><?php echo $staff['beizhu'] ?></td>
<td><?php echo $staff['yonghuid'] ?></td>
<td><?php echo date('Y / m / d', $staff['shijian']) ?></td>
<td><button onclick="location.href='handle.php?action=edit&id=<?php echo $staff['id'] ?>'">编辑</button>
<button onclick="location.href='handle.php?action=del&id=<?php echo $staff['id'] ?>'">删除</button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<!-- 添加跳转到首页, 前一页, 下一页, 尾页的功能 -->
<!-- 页码开始 -->
<p>
<?php
// 1. 分页显示多少个页码 这里定义为5个
$showPages = 5;
// 2. 分页条的起始页码
$startPage = 1;
// 3. 分页条的终止页码 终止页码等于现在最多页码
$endPage = $pages; // 当前总页数: 14
// 4. 分页条的偏移量: (当前分页条显示的页码数 - 1) / 2
$offsetPage = ($showPages -1) / 2; // 2
// 只有当前分页条数量 < 总页数, 才有必要显示出省略标记
if ($showPages < $pages) {
// 如果当前页 > 偏移量 + 1 , 应该显示...
if ($page > $offsetPage + 1) {
$startOmit = '...';
}
// 将当前分页条页码重置
if ($page > $offsetPage) {
$startPage = $page - $offsetPage;
$endPage = $page + $offsetPage;
if ($endPage > $pages) {$endPage = $pages;}
} else {
$startPage = 1;
$endPage = $showPages;
}
// 如果当前页 + 偏移量 > 总页数
if ($page + $offsetPage > $pages) {
// 原理, 就是向当前页前面进行借位
// 此时, 新的起点 = 当前位置 - (当前页 + 偏移量 - 原始位置)
$startPage = $startPage - ($page + $offsetPage - $endPage);
}
if ($showPages < $pages && $page + $offsetPage < $pages) $endOmit = '...';
}
?>
<!-- 首页 -->
<a href="<?php echo $_SERVER['PHP_SELF'] . '?p=1' ?>">首页</a>
<!-- 前一页 -->
<?php
$prev = $page - 1;
if ($page == 1) $prev = 1;
?>
<a href="<?php echo $_SERVER['PHP_SELF'] . '?p=' . $prev ?>">前一页</a>
<?php if (isset($startOmit)) : ?> <a href="#"><?php echo $startOmit ?></a> <?php endif ?>
<?php for ($i=$startPage; $i<=$endPage; $i++): ?>
<?php
$jump = sprintf('%s?p=%s', $_SERVER['PHP_SELF'], $i );
$active = ($i == $page) ? 'active' :null;
?>
<a href="<?php echo $jump ?>" class="<?php echo $active ?>"><?php echo $i ?></a>
<?php endfor ?>
<?php if (isset($endOmit)) : ?> <a href="#"><?php echo $endOmit ?></a> <?php endif ?>
<!-- 下一页 -->
<?php
$next = $page + 1;
if ($page == $pages) $next = $pages;
?>
<a href="<?php echo $_SERVER['PHP_SELF'] . '?p=' . $next ?>">下一页</a>
<!-- 尾页 -->
<a href="<?php echo $_SERVER['PHP_SELF'] . '?p='. $pages ?>">尾页</a>
<form class="form1" action="" method="get">
<input type="number" name="p"min="1" max="{$pages}" required />
<button>跳转</button>
</form>
</p>
</body>
</html>
handle.php页
<?php
require 'demo1.php';
$action = $_GET['action'];
$id = $_GET['id'];
switch ($action) {
// 编辑需要进行二步
// 1. 渲染编辑表单
case 'edit':
include 'edit.php';
break;
// 2. 执行编辑操作
case 'doedit':
$sql = 'UPDATE `jizhang` SET `jine`=:jine, `zhanghu`=:zhanghu,`chengyuan`=:chengyuan,`beizhu`=:beizhu ,`yonghuid`=:yonghuid,`shijian`=:shijian WHERE `id`=:id';
// print_r($_POST);
// $_POST['id'] = $id;
$_POST['shijian'] = strtotime($_POST['shijian']);
$stmt = $pdo->prepare($sql);
$stmt->execute($_POST);
if ($stmt->rowCount() === 1) echo '<script>alert("更新成功");location.href="demo4.php";</script>';
// 3. 删除
case 'del':
$stmt = $pdo->query("delete from `jizhang` where `id`=$id");
if ($stmt->rowCount() === 1) echo '<script>alert("删除成功");location.href="demo4.php";</script>';
break;
}
编辑页面edit.php
<?php
// 获取要被编辑的员工信息
$staff = $pdo->query("SELECT * FROM `jizhang` WHERE `id`={$id}")->fetch();
// print_r($staff);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h3>编辑消费明细</h3>
<form action="<?php echo $_SERVER['PHP_SELF'].'?action=doedit&id='. $id ?>" method="post">
<p>
<label for="jine">金额:</label>
<input type="text" id="name" name="jine" value="<?php echo $staff['jine'] ?>">
</p>
<p>
<label for="zhanghu">账户:</label>
<input type="text" id="age" name="zhanghu" value="<?php echo $staff['zhanghu'] ?>">
</p>
<input type="hidden" name="id" value="<?php echo $staff['id'] ?>">
<p>
<label for="chengyuan">成员:</label>
<input type="text" id="age" name="chengyuan" value="<?php echo $staff['chengyuan'] ?>">
</p>
<p>
<label for="beizhu">备注:</label>
<input type="text" id="position" name="beizhu" value="<?php echo $staff['beizhu'] ?>">
</p>
<p>
<label for="yonghuid">用户id:</label>
<input type="text" id="tel" name="yonghuid" value="<?php echo $staff['yonghuid'] ?>">
</p>
<p>
<label for="shijian">手机号:</label>
<input type="text" id="hiredate" name="shijian" value="<?php echo date('Y-m-d', $staff['shijian']) ?>">
</p>
<p>
<button>保存</button>
</p>
</form>
</body>
</html>
前端样式style.css
* {
margin: 0;
padding: 0;
box-sizing: border-box;
color: #555;
}
body {
display: flex;
flex-direction: column;
align-items: center;
}
/*表格样式*/
table {
width: 80%;
border: 1px solid;
border-collapse: collapse;
text-align: center;
}
table caption {
font-size: 1.2rem;
margin: 10px;
}
table td,
table th {
border: 1px solid;
padding: 5px;
}
table tr:hover {
background-color: #eee;
}
table thead tr:only-of-type {
background-color: lightblue;
}
table button {
width: 56px;
height: 26px;
}
table button:last-of-type {
color: red;
}
table button {
cursor: pointer;
margin: 0 3px;
}
/*分页条样式*/
body > p {
display: flex;
}
p > a {
text-decoration: none;
color: #555;
border: 1px solid;
padding: 5px 10px;
margin: 10px 2px;
}
.active {
background-color: red;
color: white;
border: 1px solid red;
}
效果图片
总结:分页理解的比较透了,分页省略这个有点逻辑上的复杂,以后应该会遇到很多这样的或者更复杂的逻辑,应该多看多思考。