上一篇
2025年7月最新动态:随着PHP 8.4的稳定版发布,分页功能在高并发场景下的性能优化成为开发者关注焦点,新版本对内存管理进行了改进,使得大数据量分页查询效率提升显著,同时更多开发者倾向于采用轻量级自定义分页方案替代传统框架内置组件,以获得更高的灵活性。
无论是电商网站的商品列表,还是内容管理系统的文章展示,数据量大了直接全部加载不仅拖慢速度,用户体验也极差,分页功能就像书本的目录,让用户能快速定位到想要的内容,同时减轻服务器压力。
在PHP中,我们可以通过MySQL的LIMIT
语句配合自定义分页类,轻松实现这一功能。
MySQL分页依赖LIMIT
子句:
SELECT * FROM products LIMIT 0, 10 -- 第1页,每页10条 SELECT * FROM products LIMIT 10, 10 -- 第2页
SELECT COUNT(*) FROM table
$_GET
获取(如?page=2
) 下面是一个完整的分页类实现,包含样式控制、URL参数保留等实用功能:
<?php class Pagination { private $totalItems; // 总记录数 private $itemsPerPage; // 每页条数 private $currentPage; // 当前页 private $maxPagesToShow = 5; // 显示的最大页码数 public function __construct($totalItems, $itemsPerPage = 10, $currentPage = 1) { $this->totalItems = $totalItems; $this->itemsPerPage = $itemsPerPage; $this->currentPage = max(1, min($currentPage, $this->getTotalPages())); } // 计算总页数 public function getTotalPages() { return ceil($this->totalItems / $this->itemsPerPage); } // 生成分页HTML public function render($baseUrl = '?') { if ($this->getTotalPages() <= 1) return ''; $html = '<ul class="pagination">'; // 上一页按钮 if ($this->currentPage > 1) { $html .= '<li><a href="' . $this->buildUrl($baseUrl, $this->currentPage - 1) . '">«</a></li>'; } // 页码按钮 $startPage = max(1, $this->currentPage - floor($this->maxPagesToShow / 2)); $endPage = min($this->getTotalPages(), $startPage + $this->maxPagesToShow - 1); for ($i = $startPage; $i <= $endPage; $i++) { $active = $i == $this->currentPage ? ' class="active"' : ''; $html .= '<li' . $active . '><a href="' . $this->buildUrl($baseUrl, $i) . '">' . $i . '</a></li>'; } // 下一页按钮 if ($this->currentPage < $this->getTotalPages()) { $html .= '<li><a href="' . $this->buildUrl($baseUrl, $this->currentPage + 1) . '">»</a></li>'; } $html .= '</ul>'; return $html; } // 构建带参数的URL private function buildUrl($baseUrl, $page) { $query = $_GET; $query['page'] = $page; return $baseUrl . http_build_query($query); } } ?>
<?php // 数据库连接 $db = new PDO('mysql:host=localhost;dbname=test', 'user', 'password'); // 获取总记录数 $total = $db->query("SELECT COUNT(*) FROM articles")->fetchColumn(); // 获取当前页码(默认为1) $page = isset($_GET['page']) ? (int)$_GET['page'] : 1; $perPage = 5; // 查询当前页数据 $offset = ($page - 1) * $perPage; $stmt = $db->prepare("SELECT * FROM articles ORDER BY id DESC LIMIT :offset, :perPage"); $stmt->bindValue(':offset', $offset, PDO::PARAM_INT); $stmt->bindValue(':perPage', $perPage, PDO::PARAM_INT); $stmt->execute(); $articles = $stmt->fetchAll(); // 分页实例 $pagination = new Pagination($total, $perPage, $page); ?> <!-- 显示文章列表 --> <?php foreach ($articles as $article): ?> <div class="article"> <h3><?= htmlspecialchars($article['title']) ?></h3> <p><?= substr($article['content'], 0, 100) ?>...</p> </div> <?php endforeach; ?> <!-- 显示分页导航 --> <div class="pagination-wrap"> <?= $pagination->render() ?> </div>
当表数据超过百万时,LIMIT 1000000, 10
会非常慢,解决方案:
-- 使用索引覆盖(推荐) SELECT * FROM articles WHERE id >= (SELECT id FROM articles ORDER BY id LIMIT 1000000, 1) LIMIT 10 -- 或者使用游标分页(适合无限滚动) SELECT * FROM articles WHERE id < ?last_id ORDER BY id DESC LIMIT 10
通过CSS轻松修改分页样式:
.pagination { display: flex; list-style: none; padding: 0; } .pagination li { margin: 0 5px; } .pagination li.active a { background: #007bff; color: white; } .pagination a { padding: 5px 10px; border: 1px solid #ddd; text-decoration: none; }
现代网站常通过AJAX无刷新加载分页数据:
$('.pagination a').click(function(e) { e.preventDefault(); $.get($(this).attr('href'), function(data) { $('#content').html(data); }); });
Q:分页URL如何保留其他GET参数?
A:示例中的buildUrl()
方法已经自动处理,会合并现有$_GET
参数。
Q:如何改变每页显示数量?
A:在实例化时传入第二个参数:
$pagination = new Pagination($total, 20); // 每页20条
Q:为什么总页数计算错误?
A:检查COUNT(*)
查询是否带过滤条件,确保与数据查询条件一致。
本文由 邛承教 于2025-07-31发表在【云服务器提供商】,文中图片由(邛承教)上传,本平台仅提供信息存储服务;作者观点、意见不代表本站立场,如有侵权,请联系我们删除;若有图片侵权,请您准备原始证明材料和公证书后联系我方删除!
本文链接:https://vps.7tqx.com/wenda/499105.html
发表评论