php分页显示数据库数据如何实现每页显示10条记录?
- 虚拟主机
- 2025-12-18
- 5
在Web开发中,分页显示数据库内容是一项非常常见的需求,尤其是在处理大量数据时,能够有效提升页面加载速度和用户体验,PHP作为服务器端脚本语言,结合MySQL等数据库,可以轻松实现分页功能,本文将详细介绍如何使用PHP实现数据库分页显示,包括基本原理、代码实现、优化技巧以及常见问题的解决方案。
分页的基本原理
分页的核心思想是将大量数据分割成多个小页面,每页显示固定数量的记录,用户可以通过点击“上一页”“下一页”或页码导航来浏览不同页面的数据,实现分页通常需要以下几个关键参数:
- 每页显示记录数($pageSize):定义每页要显示的数据条数,如10条、20条等。
- 总记录数($totalRows):从数据库中查询出的总数据条数。
- 总页数($totalPages):根据总记录数和每页显示数计算得出,公式为$totalPages = ceil($totalRows / $pageSize)。
- 当前页码($currentPage):用户当前所在的页码,通常通过URL参数传递,如?page=2。
数据库分页的实现步骤
连接数据库
需要使用PHP的MySQLi或PDO扩展连接到数据库,以下是使用MySQLi的示例代码:

获取分页参数
从URL中获取当前页码,并设置默认值为1,定义每页显示的记录数:
$pageSize = 10; // 每页显示10条记录 $currentPage = isset($_GET['page']) ? (int)$_GET['page'] : 1; if ($currentPage < 1) $currentPage = 1;
查询总记录数
执行一个COUNT查询来获取总记录数,用于计算总页数:

查询当前页数据
使用LIMIT和OFFSET子句查询当前页的数据。LIMIT指定每页显示的记录数,OFFSET指定从第几条记录开始查询:
$offset = ($currentPage 1) * $pageSize; $dataQuery = "SELECT id, title, content FROM articles ORDER BY id DESC LIMIT $offset, $pageSize"; $dataResult = $conn>query($dataQuery);
显示数据
遍历查询结果,将数据显示在HTML表格中:
<table border="1"> <tr> <th>ID</th> <th>标题</th> <th>内容</th> </tr> <?php while ($row = $dataResult>fetch_assoc()): ?> <tr> <td><?php echo $row['id']; ?></td> <td><?php echo htmlspecialchars($row['title']); ?></td> <td><?php echo substr(htmlspecialchars($row['content']), 0, 100) . '...'; ?></td> </tr> <?php endwhile; ?> </table>
生成分页导航
根据总页数生成页码导航,包括“上一页”“下一页”和页码链接:

echo "<div class='pagination'>"; if ($currentPage > 1) { echo "<a href='?page=" . ($currentPage 1) . "'>上一页</a> "; } for ($i = 1; $i <= $totalPages; $i++) { if ($i == $currentPage) { echo "<span>$i</span> "; } else { echo "<a href='?page=$i'>$i</a> "; } } if ($currentPage < $totalPages) { echo "<a href='?page=" . ($currentPage + 1) . "'>下一页</a>"; } echo "</div>";
优化技巧
- 缓存总记录数:如果数据更新不频繁,可以将总记录数缓存到Redis或Memcached中,避免每次分页都执行COUNT查询。
- 使用预处理语句:对于LIMIT查询,使用预处理语句可以防止SQL载入,并提高查询效率: $stmt = $conn>prepare("SELECT id, title, content FROM articles ORDER BY id DESC LIMIT ?, ?"); $stmt>bind_param("ii", $offset, $pageSize); $stmt>execute(); $dataResult = $stmt>get_result();
- 优化查询性能:确保ORDER BY字段有索引,避免全表扫描,对于大数据量表,可以考虑使用WHERE条件缩小查询范围。
完整示例代码
以下是一个完整的PHP分页示例:
<?php $host = 'localhost'; $username = 'root'; $password = ''; $database = 'test_db'; $conn = new mysqli($host, $username, $password, $database); if ($conn>connect_error) { die("连接失败: " . $conn>connect_error); } $conn>set_charset("utf8"); $pageSize = 10; $currentPage = isset($_GET['page']) ? (int)$_GET['page'] : 1; if ($currentPage < 1) $currentPage = 1; $totalRowsQuery = "SELECT COUNT(*) AS total FROM articles"; $totalRowsResult = $conn>query($totalRowsQuery); $totalRows = $totalRowsResult>fetch_assoc()['total']; $totalPages = ceil($totalRows / $pageSize); $offset = ($currentPage 1) * $pageSize; $dataQuery = "SELECT id, title, content FROM articles ORDER BY id DESC LIMIT $offset, $pageSize"; $dataResult = $conn>query($dataQuery); ?> <table border="1"> <tr> <th>ID</th> <th>标题</th> <th>内容</th> </tr> <?php while ($row = $dataResult>fetch_assoc()): ?> <tr> <td><?php echo $row['id']; ?></td> <td><?php echo htmlspecialchars($row['title']); ?></td> <td><?php echo substr(htmlspecialchars($row['content']), 0, 100) . '...'; ?></td> </tr> <?php endwhile; ?> </table> <div class="pagination"> <?php if ($currentPage > 1): ?> <a href="?page=<?php echo $currentPage 1; ?>">上一页</a> <?php endif; ?> <?php for ($i = 1; $i <= $totalPages; $i++): ?> <?php if ($i == $currentPage): ?> <span><?php echo $i; ?></span> <?php else: ?> <a href="?page=<?php echo $i; ?>"><?php echo $i; ?></a> <?php endif; ?> <?php endfor; ?> <?php if ($currentPage < $totalPages): ?> <a href="?page=<?php echo $currentPage + 1; ?>">下一页</a> <?php endif; ?> </div> <?php $conn>close(); ?>
相关问答FAQs
问题1:如何处理分页中的SQL载入问题?
解答:在获取当前页码时,应使用(int)强制类型转换,确保页码为整数,对于LIMIT子句中的参数,建议使用预处理语句(如MySQLi的prepare和bind_param方法),避免直接拼接SQL字符串。
$stmt = $conn>prepare("SELECT * FROM articles LIMIT ?, ?"); $stmt>bind_param("ii", $offset, $pageSize); $stmt>execute();
问题2:如果数据量非常大(如百万级),如何优化分页查询性能?
解答:对于大数据量表,传统的LIMIT offset, pageSize方式在offset很大时性能会下降,可以采用以下优化方法:
- 使用WHERE条件代替OFFSET:通过记录ID的范围查询,如WHERE id > last_id ORDER BY id LIMIT pageSize。
- 延迟关联(Delayed Association):先查询出ID,再通过关联查询获取完整数据,减少扫描行数。
- 使用索引覆盖扫描:确保查询字段有索引,避免回表操作。
- 分页缓存:对热门页面的结果进行缓存,减少数据库压力。