准备好的语句可以在php中保存多个查询吗

Posted

技术标签:

【中文标题】准备好的语句可以在php中保存多个查询吗【英文标题】:Can a prepared statement hold multiple queries in php 【发布时间】:2019-10-27 23:36:19 【问题描述】:

我最近试图保护我的查询免受 SQL 注入。我已经开始将用于查询的字符串转换为语句,但是,我所做的一些字符串需要同时进行多个查询,因为一个插入的 id 将作为外键添加到下一个,我将通过使用 LAST_INSERT_ID() 获得,因此我需要它们一个接一个地执行。

一个语句可以同时保存多个查询并一次执行吗?

这是之前的代码,由作者提供。

$sql = "INSERT INTO `user_info`(`first_name`, `last_name`, `phone`, `cpf`) 
            VALUES ('$firstName', '$lastName', '$phone', '$cpf');";
$sql .= "SELECT LAST_INSERT_ID() INTO @mysql_variable_here;";
$sql .= "INSERT INTO `$table`(`email`, `password`, `active`,`user_info_id`, `created`, `role_id`" . $restaurantInsert . ")
            VALUES ('$email','$password', 1, @mysql_variable_here, '$created', $role" . $restaurantValue . " );"; 
$sql .= "INSERT INTO `address`(number, street, city, state, zip, district, country, created, user_info_id)
            VALUES ('$number', '$street', '$city', '$stateCode', '$zip', '$district', 'BR', '$created', @mysql_variable_here);";

$result = $conn->multi_query($sql);```

【问题讨论】:

这不安全。没有使用multi_query 是安全的。将参数化查询与准备好的语句和事务一起使用。 $restaurantInsert$restaurantValue 中有什么内容? 【参考方案1】:

您不能在prepared query 中执行多个语句:

预处理语句的 SQL 语法不支持多语句 (即,单个字符串中的多个语句,用 ; 分隔 字符)

因此您需要分别准备和执行每个查询,使用mysqli_stmt::insert_id 为第二个和第三个查询获取适当的id 值:

$sql = "INSERT INTO `user_info`(`first_name`, `last_name`, `phone`, `cpf`) 
            VALUES (?, ?, ?, ?)";
$stmt = $conn->prepare($sql);
$stmt->bind_param('ssss', $firstName, $lastName, $phone, $cpf);
$stmt->execute();
$insert_id = $stmt->insert_id;
$stmt->close();

$sql = "INSERT INTO `$table`(`email`, `password`, `active`,`user_info_id`, `created`, `role_id`" . $restaurantInsert . ")
            VALUES (?, ?, ?, ?, ?, ?, ?)";
$stmt = $conn->prepare($sql);
$stmt->bind_param('ssiisss', $email, $password, 1, $insert_id, $created, $role, $restaurantValue);
$stmt->execute();
$stmt->close();

$sql = "INSERT INTO `address`(number, street, city, state, zip, district, country, created, user_info_id)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);";
$stmt = $conn->prepare($sql);
$country = 'BR';
$stmt->bind_param('sssssssi', $number, $street, $city, $stateCode, $zip, $district, $country, $created, $insert_id);
$stmt->execute();
$stmt->close();

请注意,我不能 100% 确定您要使用 role_id" . $restaurantInsert . " 实现什么,您可能需要适当地编辑第二个查询才能使用它。

【讨论】:

以上是关于准备好的语句可以在php中保存多个查询吗的主要内容,如果未能解决你的问题,请参考以下文章

mysqli:它可以在一个语句中准备多个查询吗?

我可以在 JDBC 准备查询中使用多个语句吗?

什么时候在 PHP Mysqli 中使用准备好的语句? - 用户表单搜索输入与选择查询

没有绑定参数的mysqli准备好的语句仍然安全吗?

我可以重新定义相同的准备好的语句吗?

更新数据库中的数据 - 准备好的语句(PHP)