使用预处理语句防止sql注入的核心做法是调用 $mysqli->prepare() 生成预处理对象,通过 bind_param() 绑定参数,最后执行 execute()。这样数据库会将 sql 模板与数据分开处理,彻底杜绝了恶意代码拼接的风险。

如何构建并执行预处理语句
构建预处理语句的关键在于使用占位符(如 ? )代替具体的值,并在绑定时明确指定数据类型。以查询用户为例,先准备包含占位符的 SQL 字符串,然后调用 bind_param('s', $user) 将变量绑定到占位符上,其中 's' 代表字符串类型。执行后,数据库会安全地替换占位符并返回结果集。

$mysqli = new mysqli("localhost", "user", "password", "database");
$sql = "SELECT id, name FROM users WHERE username = ?";
$stmt = $mysqli->prepare($sql);
$username = "admin'; DROP TABLE users;--";
$stmt->bind_param("s", $username);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
echo $row["name"] . "\n";
}
$stmt->close();
$mysqli->close();
预期输出:如果数据库中不存在名为 admin'; DROP TABLE users;-- 的用户,则不输出任何内容;若存在同名用户,则输出其姓名。不会发生表被删除的情况。
如何处理多参数与不同数据类型
当查询涉及多个条件或不同类型的数据时,需要在 bind_param() 中按顺序列出所有参数的类型标识符。例如,同时查询用户名和年龄时,类型字符串应为 'si'(分别代表 string 和 integer)。参数列表需与占位符一一对应,确保类型匹配正确,否则会导致错误或数据截断。
安装、修复、更新或打包一个基于 Python 和 PyMySQL 实现的 Windows `mysql` 命令。适用于用户希望在 PowerShell/CMD 中输入 `mysql` 时重定向到 Python 实现、需要交互式输入 MySQL 连接信息、需要同步到当前用户本地 bin 目录,或需要将该能力封装成可公开复用的 Codex skill。

$mysqli = new mysqli("localhost", "user", "password", "database");
$sql = "SELECT id, name FROM users WHERE username = ? AND age > ?";
$stmt = $mysqli->prepare($sql);
$user = "john";
$age = 18;
$stmt->bind_param("si", $user, $age);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows > 0) {
while ($row = $result->fetch_assoc()) {
echo "ID: " . $row["id"] . ", Name: " . $row["name"] . "\n";
}
} else {
echo "No results found.\n";
}
$stmt->close();
$mysqli->close();
预期输出:根据实际数据库内容,可能输出一行或多行包含 ID 和姓名的记录,或者输出 No results found.。关键在于 'si' 确保了 $age 被当作整数处理,即使传入的是字符串形式的数字也不会引发注入。
预处理语句在插入操作中的具体应用
在插入新数据时,预处理语句同样适用。只需将 SQL 模板中的占位符对应到待插入的值,并通过 bind_param() 绑定即可。这种方式不仅防止了注入,还提高了重复执行相同结构插入操作的效率。执行后,可通过 $stmt->insert_id 获取新生成的自增 ID。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










