导读:本期聚焦于小伙伴创作的《PHP和MySQL怎么做数据分页?从SQL到前端展示的完整实现方案》,敬请观看详情。面对成百上千条记录直接查询全部返回,页面加载慢且用户体验差。分页的核心是利用MySQL的LIMIT子句截取指定区间数据,再用PHP计算总页数与偏移量。本文给出基于COUNT统计与LIMIT offset,size的查询写法,说明如何通过GET参数接收页码并做越界校验,同时提供复用性较好的封装函数示例。掌握这套逻辑后,列表页响应速度显著提升,也能避免重复造轮子处理翻页链接。

在Web应用的后台列表或前台信息流中,当数据量增长到几千甚至上百万条时,一次性从MySQL查出全部记录再渲染到页面既耗费内存又拖慢响应。通过PHP配合MySQL的LIMIT机制,可以把结果集按固定大小切分成多页,每次只取当前页所需数据。这种方式既减轻了数据库压力,也让用户浏览更顺畅。

PHP和MySQL怎么做数据分页?从SQL到前端展示的完整实现方案

一、分页的底层原理

MySQL本身不提供“页”的概念,所谓分页本质上是利用LIMIT关键字控制结果集的起始位置和返回行数。假设每页显示10条,那么第n页对应的偏移量就是(n-1)*10,SQL写作LIMIT 偏移量, 每页条数。PHP的职责是根据用户请求的页码算出这个偏移量,并先通过COUNT(*)拿到总记录数,从而推算出总页数。

很多初学者容易忽略总条数查询与数据查询必须基于同一筛选条件,否则会出现页码对不上或最后一页数据缺失。另外,LIMIT在大偏移量时性能会下降,例如LIMIT 100000, 10实际要扫描十万行再丢弃,后续可借助游标或延迟关联优化,但基础分页先保证逻辑正确。

二、数据库准备与示例表

我们创建一张简单的文章表来演示。表结构包含自增主键、标题与发布时间,数据量可以自行制造一些测试行。

CREATE TABLE `article` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(100) NOT NULL,
  `created_at` datetime DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

插入测试数据可以用存储过程或简单脚本循环写入,这里不展开。重点在于后续查询都基于这张表,确保字段名与代码中的SQL保持一致,避免因为拼写错误导致空结果。

三、PHP实现基础分页逻辑

下面是一段不依赖框架的原生PHP代码,展示如何接收页码、计算偏移、执行两条SQL并渲染简易分页条。注意对页码参数做了整数化和越界保护。

<?php
// 假设已建立 $pdo 连接
$pageSize = 10;
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
if ($page < 1) {
    $page = 1;
}

// 统计总数
$countSql = "SELECT COUNT(*) FROM article";
$total = $pdo->query($countSql)->fetchColumn();
$totalPages = ceil($total / $pageSize);

if ($page > $totalPages && $totalPages > 0) {
    $page = $totalPages;
}

$offset = ($page - 1) * $pageSize;
$dataSql = "SELECT id, title, created_at FROM article ORDER BY id DESC LIMIT " . $offset . ", " . $pageSize;
$stmt = $pdo->query($dataSql);
$list = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>

上述代码先把用户传来的page转成整数,防止SQL注入和非法值。然后通过COUNT拿到总条数,用ceil计算总页数。若请求页超出范围则纠正到最后一页,这是提升健壮性的关键一步。

数据查询部分直接拼接偏移量和每页大小,因为二者都是PHP整数运算结果,不存在外部字符串注入风险。实际项目中若使用框架的查询构造器,也应显式传参而非拼字符串,保持同样的安全意识。

四、前端展示与分页导航

取回列表后,需要把数据循环输出,并生成上一页、下一页及页码链接。以下代码紧接上面的PHP变量,用简易HTML呈现。

<ul>
<?php foreach ($list as $row): ?>
  <li><?php echo htmlspecialchars($row['title']); ?> (<?php echo $row['created_at']; ?>)</li>
<?php endforeach; ?>
</ul>

<div>
  <?php if ($page > 1): ?>
    <a href="?page=<?php echo $page - 1; ?>">上一页</a>
  <?php endif; ?>
  <span>第 <?php echo $page; ?> / <?php echo $totalPages; ?> 页</span>
  <?php if ($page < $totalPages): ?>
    <a href="?page=<?php echo $page + 1; ?>">下一页</a>
  <?php endif; ?>
</div>

这里使用htmlspecialchars对标题做转义,防止存储型XSS。分页链接直接改URL的page参数,浏览器刷新即触发新的查询,逻辑简单清晰,适合后台或轻量前台。

如果页码很多,可以只显示当前页前后几页加省略号,避免链接过长。但这属于交互优化,底层依然依赖同一个page参数与相同的SQL分页规则。

五、封装为可复用函数

为避免每个列表都重写一遍计数和偏移计算,可以提炼一个函数。它接收表名、页码、每页大小,返回数据与分页信息数组。

<?php
function paginate($pdo, $table, $page, $pageSize) {
    $page = max(1, (int)$page);
    $total = $pdo->query("SELECT COUNT(*) FROM " . $table)->fetchColumn();
    $totalPages = ceil($total / $pageSize);
    $page = min($page, $totalPages ?: 1);
    $offset = ($page - 1) * $pageSize;
    $sql = "SELECT * FROM " . $table . " LIMIT " . $offset . ", " . $pageSize;
    $data = $pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC);
    return [
        'data' => $data,
        'page' => $page,
        'totalPages' => $totalPages,
        'total' => $total
    ];
}
?>

这个函数把边界处理收拢在一处,调用方只需关心传入页码。注意示例中表名直接拼接,仅适合内部固定字符串,若表名来自用户输入必须白名单校验。

在复杂业务里,可能还要接收WHERE条件和排序参数,此时建议用预处理语句绑定值,而LIMIT部分因是数字仍可安全拼接。封装后控制器代码更干净,也方便统一加缓存。

六、常见误区与优化建议

一个典型误区是只用LIMIT 10却不管页码,导致点第二页还是第一页数据。必须带上偏移量。另一个误区是在循环里执行COUNT,严重浪费连接资源,应一次统计完。

当单表超百万且常翻到很后面时,可改用“上一页最大ID”方式:WHERE id < 上次最后ID ORDER BY id DESC LIMIT 10,避免大偏移扫描。对于模糊搜索分页,建议对搜索词建索引,否则COUNT也会变慢。合理组合这些手段,PHP与MySQL的分页就能稳定支撑大多数场景。

PHPMySQL pagination修改时间:2026-08-01 18:18:34

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。