当前位置: 首页> 最新文章列表> 用 mysqli_stmt::prepare 实现分页查询

用 mysqli_stmt::prepare 实现分页查询

gitbox 2025-05-28

在开发基于 MySQL 的 PHP 应用时,为了提高查询效率和数据呈现的用户体验,我们通常会使用分页查询来分段加载数据。相比直接使用拼接 SQL 的方式,使用 mysqli_stmt::prepare 函数不仅能有效防止 SQL 注入,还能提升代码的可读性与维护性。本文将带你详细了解如何通过 mysqli_stmt::prepare 实现分页查询,并结合示例加以解析。

一、基本概念

分页查询的核心在于 SQL 的 LIMIT 子句,其语法为:

SELECT * FROM table_name LIMIT offset, page_size;

其中:

  • offset:偏移量,表示从第几条记录开始读取。

  • page_size:每页显示的记录数。

使用 mysqli_stmt::prepare 函数时,由于 LIMIT 子句的参数不能直接绑定变量,我们需要借助一点技巧来绕过这个限制。

二、准备工作

  1. 确保使用的是 MySQLi 扩展并启用了预处理语句。

  2. 数据库连接已经建立。

  3. 有一张用于查询的数据表,如 users

三、分页查询的实现步骤

步骤 1:建立数据库连接

<?php
$mysqli = new mysqli("localhost", "username", "password", "database");
if ($mysqli->connect_error) {
    die("连接失败: " . $mysqli->connect_error);
}
?>

步骤 2:设定分页参数

<?php
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
$page_size = 10;
$offset = ($page - 1) * $page_size;
?>

步骤 3:编写预处理语句

由于 LIMIT 子句的变量无法通过 bind_param 绑定,我们只能通过字符串拼接构造 SQL。但仍可使用 prepare 绑定其它条件参数:

<?php
$sql = "SELECT id, name, email FROM users ORDER BY id DESC LIMIT ?, ?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param("ii", $offset, $page_size);
$stmt->execute();
$result = $stmt->get_result();
?>

步骤 4:输出查询结果

<?php
while ($row = $result->fetch_assoc()) {
    echo "<p>{$row['id']} - {$row['name']} - {$row['email']}</p>";
}
?>

步骤 5:分页导航链接

假设总记录数为变量 $total_rows,你可以通过如下方式生成分页链接:

<?php
$total_rows = 100; // 通常需要另行查询得到总数
$total_pages = ceil($total_rows / $page_size);

for ($i = 1; $i <= $total_pages; $i++) {
    echo "<a href='https://gitbox.net/userlist.php?page=$i'>第 $i 页</a> ";
}
?>

四、完整示例代码

<?php
$mysqli = new mysqli("localhost", "username", "password", "database");
if ($mysqli->connect_error) {
    die("连接失败: " . $mysqli->connect_error);
}

$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
$page_size = 10;
$offset = ($page - 1) * $page_size;

$sql = "SELECT id, name, email FROM users ORDER BY id DESC LIMIT ?, ?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param("ii", $offset, $page_size);
$stmt->execute();
$result = $stmt->get_result();

while ($row = $result->fetch_assoc()) {
    echo "<p>{$row['id']} - {$row['name']} - {$row['email']}</p>";
}

$stmt->close();
$mysqli->close();
?>

五、总结

使用 mysqli_stmt::prepare 实现分页查询的关键在于合理构造 SQL 并理解参数绑定的限制。虽然 LIMIT 参数不能使用命名占位符,但我们仍可通过 bind_param 绑定数字类型参数来实现安全、可靠的分页功能。在实际项目中,这种方式比传统字符串拼接更安全,也更易于维护。结合页面导航逻辑,你可以构建完整的分页数据展示系统,提高系统的用户体验与性能。