什么是准备语句?
准备语句(Prepared Statement)是一种将 SQL 语句与参数分开的数据库技术。通常在应用程序中需要执行多次的 SQL 语句会被编译一次,然后传入参数来执行,这个过程中使用了准备语句。准备语句不同于一般的 SQL 语句执行,它通过占位符来代替参数,可以更好地防止 SQL 注入攻击。
为什么要使用准备语句?
像下面这样的 SQL 语句,既不稳健也不安全:
$sql = "UPDATE users SET name='".$name."', age='".$age."' WHERE id='".$id."'";
在这个 SQL 语句中,$name、$age 和 $id 都是用户输入的变量。通过字符串拼接的方式生成 SQL 语句,很容易遭受 SQL 注入攻击。使用准备语句,可以将数据和 SQL 语句分开,并对数据进行参数化处理。
使用准备语句更新表的步骤
步骤一:连接数据库
在 PHP 中,可以使用 mysqli 函数来连接 MySQL 数据库。
$servername = "localhost";
$username = "root";
$password = "12345";
$dbname = "test";
// 创建连接
$conn = new mysqli($servername, $username, $password, $dbname);
// 检测连接
if ($conn->connect_error) {
die("连接失败: " . $conn->connect_error);
}
步骤二:准备 SQL 语句
在准备语句中,使用问号(?)作为占位符代替变量。
$sql = "UPDATE users SET name=?, age=? WHERE id=?";
上面的 SQL 语句中,使用 ? 占位符代替了变量 $name、$age 和 $id。
步骤三:准备语句
使用 mysqli_prepare 函数来准备语句。
$stmt = mysqli_prepare($conn, $sql);
mysqli_prepare 函数接受两个参数:连接对象 $conn 和 SQL 语句 $sql。注意,如果 SQL 语句中使用了命名占位符,如 :name,那么可以使用 pdo_prepare 函数准备语句,如下所示:
$stmt = $pdo->prepare('UPDATE users SET name = :name, age = :age WHERE id = :id');
步骤四:绑定参数
将参数绑定到准备语句上。
$name = "Jane";
$age = 30;
$id = 1;
mysqli_stmt_bind_param($stmt, "ssi", $name, $age, $id);
mysqli_stmt_bind_param 函数接受几个参数:准备语句 $stmt、参数绑定格式 "ssi" 和参数 $name、$age 和 $id,参数绑定格式取决于参数的类型。在这个例子中,$name 和 $age 的类型是字符串,$id 的类型是整数。参数绑定格式 "ssi" 中的每个字母代表一个参数类型。
步骤五:执行准备语句
使用 mysqli_stmt_execute 函数执行准备语句。
mysqli_stmt_execute($stmt);
步骤六:关闭准备语句和数据库连接
使用 mysqli_stmt_close 和 mysqli_close 函数关闭准备语句和数据库连接。
mysqli_stmt_close($stmt);
mysqli_close($conn);
完整的代码示例
下面是一个完整的 PHP 代码示例,使用准备语句更新表中的数据。
$servername = "localhost";
$username = "root";
$password = "12345";
$dbname = "test";
// 创建连接
$conn = new mysqli($servername, $username, $password, $dbname);
// 检测连接
if ($conn->connect_error) {
die("连接失败: " . $conn->connect_error);
}
// 准备 SQL 语句
$sql = "UPDATE users SET name=?, age=? WHERE id=?";
// 准备语句
$stmt = mysqli_prepare($conn, $sql);
// 绑定参数
$name = "Jane";
$age = 30;
$id = 1;
mysqli_stmt_bind_param($stmt, "ssi", $name, $age, $id);
// 执行准备语句
mysqli_stmt_execute($stmt);
// 关闭准备语句和数据库连接
mysqli_stmt_close($stmt);
mysqli_close($conn);
总结
使用准备语句更新表可以更好地保护数据库免受 SQL 注入攻击。准备语句的使用过程大致包括以下步骤:连接数据库、准备 SQL 语句、准备语句、绑定参数、执行准备语句、关闭准备语句和数据库连接。
虽然使用准备语句比直接拼接 SQL 语句更安全,但也不完全免除 SQL 注入攻击的风险。为了更好地保护数据库,需要在应用程序中采取其他的安全措施,如验证用户输入,限制用户的权限等等。