php和mysql实现分页
实现分页的基本原理
分页的核心是通过SQL的LIMIT子句控制数据查询范围,结合前端传递的页码参数动态计算偏移量。MySQL中分页查询格式为LIMIT offset, page_size,其中offset = (当前页码 - 1) * 每页条数。
数据库准备
创建示例数据表并插入测试数据:
CREATE TABLE articles (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
content TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 插入测试数据(示例插入20条)
INSERT INTO articles (title, content) VALUES
('标题1', '内容1'), ('标题2', '内容2'), ..., ('标题20', '内容20');
PHP分页实现代码
<?php
// 数据库连接配置
$host = 'localhost';
$dbname = 'test_db';
$user = 'root';
$pass = '';
$charset = 'utf8mb4';
$dsn = "mysql:host=$host;dbname=$dbname;charset=$charset";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
];
try {
$pdo = new PDO($dsn, $user, $pass, $options);
} catch (PDOException $e) {
die("数据库连接失败: " . $e->getMessage());
}
// 分页参数处理
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
$perPage = 5; // 每页显示条数
$offset = ($page - 1) * $perPage;
// 查询总记录数
$totalStmt = $pdo->query("SELECT COUNT(*) FROM articles");
$total = $totalStmt->fetchColumn();
// 计算总页数
$totalPages = ceil($total / $perPage);
// 查询当前页数据
$stmt = $pdo->prepare("SELECT * FROM articles LIMIT :offset, :perPage");
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->bindValue(':perPage', $perPage, PDO::PARAM_INT);
$stmt->execute();
$articles = $stmt->fetchAll();
?>
<!-- 显示分页数据 -->
<!DOCTYPE html>
<html>
<head>
<title>分页示例</title>
<style>.pagination { margin-top: 20px; }</style>
</head>
<body>
<h1>文章列表</h1>
<ul>
<?php foreach ($articles as $article): ?>
<li>
<h3><?= htmlspecialchars($article['title']) ?></h3>
<p><?= nl2br(htmlspecialchars($article['content'])) ?></p>
</li>
<?php endforeach; ?>
</ul>
<!-- 分页导航 -->
<div class="pagination">
<?php if ($page > 1): ?>
<a href="?page=<?= $page - 1 ?>">上一页</a>
<?php endif; ?>
<?php for ($i = 1; $i <= $totalPages; $i++): ?>
<a href="?page=<?= $i ?>" <?= $i == $page ? 'style="font-weight:bold"' : '' ?>>
<?= $i ?>
</a>
<?php endfor; ?>
<?php if ($page < $totalPages): ?>
<a href="?page=<?= $page + 1 ?>">下一页</a>
<?php endif; ?>
</div>
</body>
</html>
优化建议
使用预处理语句防止SQL注入,所有用户输入参数都应经过过滤或类型转换。示例中通过(int)$_GET['page']确保页码为整数。
对于大型数据集,考虑在分页查询中添加WHERE条件优化,例如只查询需要显示的列而非SELECT *,或者对常用分页字段添加索引。
替代方案
对于超大型数据表(百万级以上),传统LIMIT分页在后期页码会出现性能问题。可考虑以下优化方案:
-- 使用WHERE子句优化(需有序号字段或唯一索引)
SELECT * FROM articles WHERE id > 上一页最后ID ORDER BY id LIMIT 5;
-- 或使用游标分页
SELECT * FROM articles ORDER BY id LIMIT 5 OFFSET 0;
前端可采用异步加载方式(AJAX)实现无刷新分页,提升用户体验。






