PHP实现简单分页,SQL limit用法
时间:2026-10-9 07:37 作者:emer 分类: 无
前言
做网站列表页,数据太多一页显示不完,需要分页。PHP+MySQL做分页很简单,就是用SQL的limit。本文写个完整的分页示例,直接拿去用。
一、分页原理
分页就两件事:
- 查总条数:看看一共有多少条数据
- 查当前页数据:用limit取当前页要显示的那几条
公式:
偏移量 = (当前页 - 1) × 每页条数
比如每页10条,第3页:
偏移量 = (3 - 1) × 10 = 20
SQL: SELECT * FROM users LIMIT 20, 10
二、SQL limit用法
语法
SELECT * FROM 表名 LIMIT 偏移量, 每页条数
例子
-- 取前10条
SELECT * FROM users LIMIT 0, 10;
-- 取第11-20条
SELECT * FROM users LIMIT 10, 10;
-- 取第21-30条
SELECT * FROM users LIMIT 20, 10;
三、完整分页代码
第一步:接收当前页码
<?php
// 当前页,默认第1页
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// 每页显示多少条
$pageSize = 10;
// 计算偏移量
$offset = ($page - 1) * $pageSize;
第二步:查总条数
// 连接数据库
$conn = mysqli_connect('127.0.0.1', 'root', '123456', 'test', 3306);
mysqli_set_charset($conn, 'utf8mb4');
// 查总条数
$sql = "SELECT COUNT(*) as total FROM users";
$result = mysqli_query($conn, $sql);
$row = mysqli_fetch_assoc($result);
$total = $row['total'];
// 算总页数
$totalPage = ceil($total / $pageSize);
第三步:查当前页数据
// 查当前页的数据
$sql = "SELECT id, name, age FROM users ORDER BY id DESC LIMIT $offset, $pageSize";
$result = mysqli_query($conn, $sql);
// 取数据
$list = [];
while ($row = mysqli_fetch_assoc($result)) {
$list[] = $row;
}
第四步:显示数据和分页导航
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>用户列表</title>
</head>
<body>
<h1>用户列表</h1>
<table border="1">
<tr>
<th>ID</th>
<th>姓名</th>
<th>年龄</th>
</tr>
<?php foreach ($list as $item): ?>
<tr>
<td><?php echo $item['id']; ?></td>
<td><?php echo $item['name']; ?></td>
<td><?php echo $item['age']; ?></td>
</tr>
<?php endforeach; ?>
</table>
<p>共 <?php echo $total; ?> 条,第 <?php echo $page; ?> / <?php echo $totalPage; ?> 页</p>
<p>
<?php if ($page > 1): ?>
<a href="?page=<?php echo $page - 1; ?>">上一页</a>
<?php endif; ?>
<?php for ($i = 1; $i <= $totalPage; $i++): ?>
<?php if ($i == $page): ?>
<strong><?php echo $i; ?></strong>
<?php else: ?>
<a href="?page=<?php echo $i; ?>"><?php echo $i; ?></a>
<?php endif; ?>
<?php endfor; ?>
<?php if ($page < $totalPage): ?>
<a href="?page=<?php echo $page + 1; ?>">下一页</a>
<?php endif; ?>
</p>
</body>
</html>
四、封装成分页函数
function pagination($page, $totalPage, $url = '')
{
$html = '';
if ($page > 1) {
$html .= '<a href="' . $url . '?page=' . ($page - 1) . '">上一页</a> ';
}
for ($i = 1; $i <= $totalPage; $i++) {
if ($i == $page) {
$html .= '<strong style="margin:0 5px;">' . $i . '</strong> ';
} else {
$html .= '<a href="' . $url . '?page=' . $i . '" style="margin:0 5px;">' . $i . '</a> ';
}
}
if ($page < $totalPage) {
$html .= '<a href="' . $url . '?page=' . ($page + 1) . '">下一页</a>';
}
return $html;
}
// 使用
echo pagination($page, $totalPage);
五、常见坑
坑1:页码没做限制
用户输入 ?page=999,结果查出来是空的。
解决: 限制页码范围:
$page = max(1, min($page, $totalPage));
坑2:offset算错了
$offset = $page * $pageSize; // 错!
正确:
$offset = ($page - 1) * $pageSize; // 对!
坑3:总条数查错了
带条件查询的时候,总条数也要带条件。
比如:
// 带条件查数据
$sql = "SELECT * FROM users WHERE status = 1 LIMIT $offset, $pageSize";
// 总条数也要带条件
$sql = "SELECT COUNT(*) FROM users WHERE status = 1";
坑4:大表分页越查越慢
数据多了以后,LIMIT 100000, 10 会很慢。
原因: MySQL要先扫描前面10万条再跳过。
优化:
-- 先查id,再关联
SELECT u.* FROM users u
INNER JOIN (SELECT id FROM users ORDER BY id LIMIT 100000, 10) t
ON u.id = t.id;
六、带搜索条件的分页
// 搜索关键词
$keyword = isset($_GET['keyword']) ? trim($_GET['keyword']) : '';
// 拼WHERE
$where = "WHERE 1=1";
if ($keyword) {
$where .= " AND name LIKE '%$keyword%'";
}
// 总条数
$sql = "SELECT COUNT(*) as total FROM users $where";
// 当前页数据
$sql = "SELECT * FROM users $where ORDER BY id DESC LIMIT $offset, $pageSize";
总结
记住:
- 分页就是
LIMIT 偏移量, 每页条数 - 偏移量 = (当前页 - 1) × 每页条数
- 先查总条数,再算总页数
- 页码要做限制,不能超出范围
- 带条件查询时,总条数也要带条件
核心公式:
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
$pageSize = 10;
$offset = ($page - 1) * $pageSize;
$sql = "SELECT * FROM users LIMIT $offset, $pageSize";
遇到问题加QQ23979811 协助处理