一、原生分页
1、pageData.php文件
根据上节课学习内容,使用pdo对数据库进行操作处理,读取具体数据和总条数进行渲染,分页按 总条数 / 每页多少条 得出页码。
/**
* 分页 limit子句
* pageSize每页获取多绍条数据,当前页page 偏移量
* order by 子句存在limit前面
*/
// 页码来自get参数
$page = $_GET['page'] ?? 1;
// 越界检测
$page = $page<1 ? 1: $page;
// 每页显示数量
$pageSize = 4;
// 偏移量 offset
$offset = ($page - 1) * $pageSize;
$db = new PDO('mysql:host=localhost;dbname=phpcn22','root','root');
$sql = 'select id,uname,status from user limit ?,?;';
$stmt = $db->prepare($sql);
$stmt->bindParam(1,$offset,PDO::PARAM_INT);
$stmt->bindParam(2,$pageSize,PDO::PARAM_INT);
$stmt->execute();
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);
// print_r($users);
// 计算总页数
// 1. 计算数据表里所有的记录
$sql = 'SELECT COUNT(id) AS count FROM user;';
$stmt = $db->prepare($sql);
$stmt->execute();
// 获取总页数方法1 :
/* 查询结果里的字段绑定到一个变量上
$stmt->bindColumn('count',$total);
$stmt->fetch();
*/
// 获取总页数方法2 :
$total = $stmt->fetch()['count'];
$pages = ceil( $total / $pageSize );
2、index.php文件
<?php
require 'pageData.php';
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Document</title>
</head>
<body>
<table border="1">
<caption>用户表</caption>
<thead>
<tr>
<th>编号</th>
<th>用户名</th>
<th>手机号码</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<?php foreach ($users as $user): ?>
<tr>
<td><?= $user['id'] ?></td>
<td><?= $user['uname'] ?></td>
<td>13800138000</td>
<td><?= $user['status'] == 1 ? '正常' : '注销' ?></td>
<td>
<button>删除</button>
<button>编辑</button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<p>
<!-- 动态生成分页 -->
<?php
// 上一页
$prev = $page - 1;
// if (expr) {expr1}
// 系统先判断expr是否为真,如果是,则执行后面的语句,
// 如果否,后面的语句就没有执行的必要了;转换成IF语句为
if ($page == 1) $prev = 1;
if ($page != 1) :
?>
<a href="<?= '?page=' . $prev ?>">上一页</a>
<?php endif; ?>
<?php for($i=1; $i<=$pages; $i++) :
$active = ($i == $page) ? 'active' : null;
?>
<a href="<?= '?page=' . $i ?>" class="<?= $active ?>"><?= $i ?></a>
<?php endfor ?>
<?php
// 下一页
$next = $page + 1;
if ($next == $page) $next = $page;
// 当前页码不等于总页面,显示下一页
if ($page != $pages) : ?>
<a href="<?= '?page=' . $next ?>">下一页</a>
<?php endif; ?>
</p>
</body>
</html>
3、运行结果:
重点是index.php文件的 【动态生成分页】代码:
但是一个是混编,一个没有前后端分离,阅读起来有点费劲。
二、layui分页
- 首先登录layui官网下载插件:https://layui.gitee.io/v2/
- 然后进行css、js代码加载;
— <link rel="stylesheet" href="layui/css/layui.css">
— <script src="layui/layui.js"></script> - 具体使用可参考官网文档:https://layui.gitee.io/v2/docs/modules/laypage.html
1、PDO数据库操作不变。
2、index.php文件
<?php
require 'pageData.php';
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="layui/css/layui.css">
<title>Document</title>
</head>
<body>
<table border="1">
<caption>用户表</caption>
<thead>
<tr>
<th>编号</th>
<th>用户名</th>
<th>手机号码</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<?php foreach ($users as $user): ?>
<tr>
<td><?= $user['id'] ?></td>
<td><?= $user['uname'] ?></td>
<td>13800138000</td>
<td><?= $user['status'] == 1 ? '正常' : '注销' ?></td>
<td>
<button>删除</button>
<button>编辑</button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<div id="page">
</div>
<script src="layui/layui.js"></script>
<script>
layui.use(['laypage'],function(){
var laypage = layui.laypage;
//执行一个laypage实例
laypage.render({
elem: 'page' //注意,这里的 test1 是 ID,不用加 # 号
,
count: <?= $total ?> //数据总数,从服务端得到
,
limit: <?= $pageSize ?>,
curr: <?= $page ?>
,
layout: ['prev', 'page', 'next', 'count'],
jump: function(obj, first) {
// obj包含了当前分页的所有参数,比如:
//首次不执行
if (!first) {
window.location.href = '?page=' + obj.curr;
}
}
});
});
</script>
2、运行结果:
使用layui插件方便快捷,代码易读性良好!
三、MVC架构
MVC框架理解:
- M:model模型,对数据库管理、操作;
- V:view试图,前端视图格式化;
- C:controller控制器,请求派发器,用户点击等事件进行处理。
案例:
1、Medel.php文件
<?php
// 模型 数据操作
namespace mvc_demo;
use PDO;
class Model
{
public function getData()
{
return (new PDO('mysql:host=localhost;dbname=phpcn22;','root','root'))
->query('select id, uname, status from user order by id asc limit 0,5')
->fetchAll(PDO::FETCH_ASSOC);
}
public function editData()
{
}
}
2、View.php文件
<?php
namespace mvc_demo;
class view
{
public function fetch($data)
{
$table = '<table>';
$table .= '<caption>用户信息表</caption>';
$table .= '<tr><th>编号</th><th>姓名</th><th>手机号</th><th>状态</th><th>操作</th></tr>';
foreach ($data as $user) {
$user['status'] = $user['status'] == 1 ? '正常' : '注销';
$table .= '<tr>';
$table .= '<td>' . $user['id'] . '</td>';
$table .= '<td>' . $user['uname'] . '</td>';
$table .= '<td>13800138000</td>';
$table .= '<td>' . $user['status'] . '</td>';
$table .= '<td><button>删除</button><button>编辑</button></td>';
$table .= '</tr>';
}
$table .= '</table>';
return $table;
}
}
$data = (new Model)->getData();
echo (new View)->fetch($data);
3、Controller.php文件
<?php
namespace mvc_demo;
require 'Model.php';
require 'View.php';
class Controller
{
protected $model;
protected $view;
// 依赖注入其实本质上是指对类的依赖通过构造器完成自动注入
// 通过构造方法将外部对象初始化,实现了外部依赖注入的对象在类内部的共享/复用
public function __construct(Model $model,View $view)
{
$this->model = $model;
$this->view = $view;
}
// 在控制器架构方法和操作方法中,一旦对参数进行对象类型约束则会自动触发依赖注入
// 在操作方法中注入
public function index(Model $model,View $view)
{
// 1. 获取数据 Model
$data = $this->model->getData();
// 2. 视图渲染 View
$this->view->fetch($data);
}
public function edit(Model $model)
{
$this->model->editData();
}
}
$model = new Model;
$view = new View;
//echo ($new Controller($model,$view))->index($model, $view);
$c = new Controller($model,$view);
call_user_func_array([$c,'index'],[$model,$view]);
运行结果:
总结:
`Model`:数据库类,对数据库管理、操作;
`View`:视图类,对前天视图的格式化;
`Controller`:控制器类,请求派发器,对用户事件进行处理
- 控制方法,构造方法,调用方法,获取数据
`依赖注入`:将模型和视图的实例化过程,放在控制器的外部进行实现,作为参数,注入到控制器的方法中。