zuojiankuohaophpcnp>制作php分页功能的核心是使用mysql的limit子句实现数据分块加载,1. 获取总记录数以计算总页数;2. 定义每页显示条数;3. 从get参数获取并验证当前页码;4. 计算偏移量(($currentpage - 1) * $recordsperpage);5. 构建并执行带limit的sql查询;6. 展示数据并生成包含上一页、下一页及页码的导航链接,同时需处理url参数保留、索引优化、避免sql_calc_found_rows,并可采用where id > last_id等策略提升性能,最终确保分页功能高效且用户体验良好。</p>

制作PHP分页功能,尤其依赖MySQL数据库时,核心在于运用SQL的
LIMIT
OFFSET
要实现基于
LIMIT
SELECT COUNT(*) FROM your_table
$_GET['page']
LIMIT
($currentPage - 1) * $recordsPerPage
SELECT * FROM your_table ORDER BY some_column LIMIT offset, recordsPerPage
下面是一个使用PDO连接数据库的简化示例:
立即学习“PHP免费学习笔记(深入)”;
<?php
// 假设你已经建立了数据库连接 $pdo
// $pdo = new PDO("mysql:host=localhost;dbname=your_database;charset=utf8", "username", "password");
// $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 开启错误报告
$recordsPerPage = 10; // 每页显示多少条记录
$currentPage = isset($_GET['page']) ? (int)$_GET['page'] : 1;
// 确保当前页码至少为1
if ($currentPage < 1) {
$currentPage = 1;
}
try {
// 1. 获取总记录数
$stmt = $pdo->query("SELECT COUNT(*) FROM articles");
$totalRecords = $stmt->fetchColumn();
// 2. 计算总页数
$totalPages = ceil($totalRecords / $recordsPerPage);
// 确保当前页码不超过总页数(如果总页数为0,则currentPage保持1)
if ($totalPages > 0 && $currentPage > $totalPages) {
$currentPage = $totalPages;
}
// 3. 计算查询的偏移量
$offset = ($currentPage - 1) * $recordsPerPage;
// 4. 获取当前页的数据
$sql = "SELECT id, title, content FROM articles ORDER BY id DESC LIMIT :offset, :limit";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':offset', $offset, PDO::PARAM_INT);
$stmt->bindParam(':limit', $recordsPerPage, PDO::PARAM_INT);
$stmt->execute();
$articles = $stmt->fetchAll(PDO::FETCH_ASSOC);
// 5. 显示数据 (这里只是一个简单示例,实际应用中会更复杂)
echo "<h2>文章列表</h2>";
if (empty($articles) && $totalRecords == 0) {
echo "<p>目前还没有任何文章。</p>";
} elseif (empty($articles) && $totalRecords > 0) {
echo "<p>当前页没有内容,可能是页码过大。</p>";
} else {
echo "<ul>";
foreach ($articles as $article) {
echo "<li>" . htmlspecialchars($article['title']) . "</li>";
}
echo "</ul>";
}
// 6. 生成分页链接
echo "<nav style='margin-top: 20px;'>";
echo "<span>总记录数: {$totalRecords}</span> | ";
echo "<span>总页数: {$totalPages}</span> | ";
echo "<span>当前页: {$currentPage}</span>";
echo "<br>";
if ($currentPage > 1) {
echo "<a href='?page=" . ($currentPage - 1) . "'>上一页</a> ";
}
// 显示一部分页码,避免过多
$startPage = max(1, $currentPage - 2);
$endPage = min($totalPages, $currentPage + 2);
for ($i = $startPage; $i <= $endPage; $i++) {
$activeClass = ($i == $currentPage) ? 'style="font-weight: bold; color: blue;"' : '';
echo "<a href='?page=$i' {$activeClass}>$i</a> ";
}
if ($currentPage < $totalPages) {
echo "<a href='?page=" . ($currentPage + 1) . "'>下一页</a>";
}
echo "</nav>";
} catch (PDOException $e) {
echo "数据库错误: " . $e->getMessage();
}
?>LIMIT
简单的
LIMIT offset, count
LIMIT
其根本原因在于,MySQL在执行
LIMIT offset, count
count
offset + count
OFFSET
OFFSET
针对这种性能瓶颈,有一些常用的优化策略:
WHERE id > last_id
SELECT * FROM articles WHERE id > :last_id ORDER BY id ASC LIMIT :limit
SELECT t1.* FROM articles t1 JOIN (SELECT id FROM articles ORDER BY id DESC LIMIT :offset, :limit) AS t2 ON t1.id = t2.id
COUNT(*)
ORDER BY
WHERE
ORDER BY
SQL_CALC_FOUND_ROWS
COUNT(*)
SELECT ... LIMIT
很多时候,分页不只是一个
page
page
GET参数传递: 最常见且直接的方式。生成分页链接时,需要确保保留当前URL中除了
page
$_GET
$queryString = $_GET; // 复制当前所有GET参数 unset($queryString['page']); // 移除当前的page参数 // 生成基础查询字符串 $baseQuery = http_build_query($queryString); // 生成分页链接时,将新的page参数追加到基础查询字符串 // 例如: <a href="?<?php echo $baseQuery; ?>&page=<?php echo $i; ?>">
这样,无论用户在哪个分类、用什么关键词搜索,点击分页链接时,这些筛选条件都能被保留下来。
路由系统集成: 在使用现代PHP框架(如Laravel, Symfony)时,它们通常有强大的路由系统。你可以定义更“漂亮”的URL结构,例如
/articles/category/tech/page/3
AJAX分页(无刷新加载): 这种方式通过JavaScript异步请求数据,然后更新页面内容,而无需重新加载整个页面。这提供了更流畅的用户体验。
history.pushState
replaceState
会话(Session)/Cookie管理: 这种方式相对少见,主要用于更复杂的状态管理,比如用户在多页操作中需要记住筛选条件。但对于简单的分页,直接通过URL参数传递更符合RESTful原则,也更利于分享和搜索引擎抓取。过度依赖Session可能导致状态管理复杂化,并增加服务器负担。
选择哪种方式,很大程度上取决于你的项目需求、对用户体验的追求以及对SEO的考量。对于大多数内容展示型网站,GET参数传递配合路由系统,加上可选的AJAX优化,通常是比较均衡的选择。
设计分页界面,不仅仅是把数字罗列出来那么简单。我见过一些网站,分页做得密密麻麻,几百个页码挤在一起,根本点不准。用户体验在这里变得尤为重要,它直接影响了用户是否能流畅地浏览你的内容,甚至决定了他们会不会继续留在你的网站。
以下是一些常见的分页设计模式和用户体验考量:
...
1 ... 5 6 [7] 8 9 ... 100
<nav aria-label="Pagination">
aria-current="page"
选择哪种模式,要根据你的内容类型和目标用户来决定。对于博客文章或新闻列表,经典的数字分页加省略号通常是最佳选择;而对于图片画廊或社交媒体动态,无限滚动或“加载更多”可能更受欢迎。核心目标是让用户能够轻松、愉快地访问到他们想要的内容。
以上就是PHP怎样制作分页功能?LIMIT分页算法实现的详细内容,更多请关注php中文网其它相关文章!
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号