使用 mysqli 预处理语句的核心流程是调用 prepare() 创建模板,通过 bind_param() 绑定变量并指定类型,最后用 execute() 执行查询。这种机制能有效防止 sql 注入,并将 sql 结构与数据分离。下面通过一个具体的用户注册场景来演示如何配合使用这三个方法。

如何绑定不同类型的数据?
bind_param() 的第一个参数是类型字符串,后续参数是实际变量的引用。类型字符包括 i (整数)、d (双精度浮点数)、s (字符串) 和 b (二进制大对象)。必须确保类型字符串的长度与后续变量数量一致,且变量必须是引用传递(&)。

$mysqli = new mysqli("localhost", "user", "password", "database");
if ($mysqli->connect_error) {
die("连接失败: " . $mysqli->connect_error);
}
$sql = "INSERT INTO users (username, email, age) VALUES (?, ?, ?)";
$stmt = $mysqli->prepare($sql);
$username = "john_doe";
$email = "john@example.com";
$age = 25;
// 绑定参数:s=字符串, s=字符串, i=整数
$stmt->bind_param("ssi", $username, $email, $age);
// 执行语句
$stmt->execute();
if ($stmt->affected_rows > 0) {
echo "插入成功,ID: " . $stmt->insert_id;
} else {
echo "插入失败: " . $stmt->error;
}
$stmt->close();
$mysqli->close();预期结果:控制台输出 “插入成功,ID: [新插入行的ID]”。如果数据库约束冲突(如用户名重复),则输出 “插入失败: [错误信息]”。
如何处理查询返回的结果?
对于 SELECT 查询,在执行 execute() 后,需要使用 store_result() 将结果集存储在客户端,然后通过 bind_result() 将列绑定到 PHP 变量,最后用 fetch() 逐行获取数据。这与插入操作不同,插入主要关注 affected_rows 或 insert_id。
安装、修复、更新或打包一个基于 Python 和 PyMySQL 实现的 Windows `mysql` 命令。适用于用户希望在 PowerShell/CMD 中输入 `mysql` 时重定向到 Python 实现、需要交互式输入 MySQL 连接信息、需要同步到当前用户本地 bin 目录,或需要将该能力封装成可公开复用的 Codex skill。

$mysqli = new mysqli("localhost", "user", "password", "database");
$sql = "SELECT id, username, email FROM users WHERE age > ?";
$stmt = $mysqli->prepare($sql);
$minAge = 18;
$stmt->bind_param("i", $minAge);
$stmt->execute();
// 绑定结果变量
$stmt->bind_result($id, $username, $email);
// 存储结果集
$stmt->store_result();
echo "找到 " . $stmt->num_rows . " 个用户:<br>";
while ($stmt->fetch()) {
echo "ID: $id, 用户名: $username, 邮箱: $email<br>";
}
$stmt->free_result();
$stmt->close();
$mysqli->close();预期结果:控制台输出所有年龄大于 18 的用户列表。如果未找到匹配项,则输出 “找到 0 个用户:”。
如果 bind_param 的变量在 execute 前被修改会怎样?
由于 bind_param() 传递的是变量的引用(reference),如果在 bind_param() 之后、execute() 之前修改变量的值,execute() 将使用修改后的新值进行查询,而不是绑定时的旧值。这是预处理语句的一个关键特性,允许复用同一个语句对象处理不同数据。
$mysqli = new mysqli("localhost", "user", "password", "database");
$sql = "SELECT username FROM users WHERE id = ?";
$stmt = $mysqli->prepare($sql);
$id = 1;
$stmt->bind_param("i", $id);
// 在 execute 前修改变量
$id = 2;
$stmt->execute();
$stmt->bind_result($username);
$stmt->fetch();
echo "查询到的用户名是: " . $username; // 输出 ID 为 2 的用户名,而非 1
$stmt->close();
$mysqli->close();预期结果:输出 ID 为 2 的用户名。这证明了变量是按引用绑定的,执行时取的是当前内存中的值。

















