php 实现分页查询
PHP 实现分页查询的方法
分页查询是 Web 开发中常见的需求,以下是一种典型的实现方式,适用于 MySQL 数据库。
数据库查询与分页逻辑
假设有一个 articles 表,需要分页显示数据:

// 连接数据库
$db = new PDO('mysql:host=localhost;dbname=test', 'username', 'password');
// 获取当前页码,默认为第1页
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
$perPage = 10; // 每页显示数量
// 计算总记录数和总页数
$total = $db->query('SELECT COUNT(*) FROM articles')->fetchColumn();
$totalPages = ceil($total / $perPage);
// 确保页码在有效范围内
$page = max($page, 1);
$page = min($page, $totalPages);
// 计算偏移量
$offset = ($page - 1) * $perPage;
// 查询当前页数据
$stmt = $db->prepare('SELECT * FROM articles LIMIT :limit OFFSET :offset');
$stmt->bindValue(':limit', $perPage, PDO::PARAM_INT);
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->execute();
$articles = $stmt->fetchAll(PDO::FETCH_ASSOC);
分页导航生成
在页面底部显示分页导航:

// 生成分页链接
$pagination = '';
if ($totalPages > 1) {
$pagination .= '<div class="pagination">';
// 上一页链接
if ($page > 1) {
$pagination .= '<a href="?page='.($page - 1).'">上一页</a>';
}
// 页码链接
for ($i = 1; $i <= $totalPages; $i++) {
if ($i == $page) {
$pagination .= '<span class="current">'.$i.'</span>';
} else {
$pagination .= '<a href="?page='.$i.'">'.$i.'</a>';
}
}
// 下一页链接
if ($page < $totalPages) {
$pagination .= '<a href="?page='.($page + 1).'">下一页</a>';
}
$pagination .= '</div>';
}
// 输出分页导航
echo $pagination;
使用 Bootstrap 样式
如果需要更美观的分页样式,可以结合 Bootstrap:
$pagination = '<nav aria-label="Page navigation"><ul class="pagination">';
if ($page > 1) {
$pagination .= '<li class="page-item"><a class="page-link" href="?page='.($page - 1).'">Previous</a></li>';
}
for ($i = 1; $i <= $totalPages; $i++) {
$active = ($i == $page) ? ' active' : '';
$pagination .= '<li class="page-item'.$active.'"><a class="page-link" href="?page='.$i.'">'.$i.'</a></li>';
}
if ($page < $totalPages) {
$pagination .= '<li class="page-item"><a class="page-link" href="?page='.($page + 1).'">Next</a></li>';
}
$pagination .= '</ul></nav>';
安全注意事项
- 始终验证和过滤用户输入的页码参数
- 使用预处理语句防止 SQL 注入
- 对大量数据分页时考虑性能优化,如添加适当索引
性能优化建议
对于大型数据集,传统 LIMIT/OFFSET 分页在深分页时性能较差。替代方案包括:
// 使用"上一页/下一页"方式代替页码导航
// 或使用基于游标的分页(记录最后显示的ID)
$lastId = isset($_GET['last_id']) ? (int)$_GET['last_id'] : 0;
$stmt = $db->prepare('SELECT * FROM articles WHERE id > :last_id ORDER BY id LIMIT :limit');
$stmt->bindValue(':last_id', $lastId, PDO::PARAM_INT);
$stmt->bindValue(':limit', $perPage, PDO::PARAM_INT);






