php - 我可以在准备好的语句中参数化表名吗?

标签 php mysql sql

我已经多次使用 mysqli_stmt_bind_param 函数。但是,如果我将试图防止 SQL 注入(inject)的变量分开,则会遇到错误。

这是一些代码示例:

function insertRow( $db, $mysqli, $new_table, $Partner, $Merchant, $ips, $score, $category, $overall, $protocol )
{
    $statement = $mysqli->prepare("INSERT INTO " .$new_table . " VALUES (?,?,?,?,?,?,?);");
    mysqli_stmt_bind_param( $statment, 'sssisss', $Partner, $Merchant, $ips, $score, $category, $overall, $protocol );
    $statement->execute();
}

是否有可能以某种方式替换 .$new_table.与另一个问号语句串联,创建另一个绑定(bind)参数语句,或者添加到现有的语句中以防止 SQL 注入(inject)?

像这样或某种形式:

function insertRow( $db, $mysqli, $new_table, $Partner, $Merchant, $ips, $score, $category, $overall, $protocol )
{    
    $statement = $mysqli->prepare("INSERT INTO (?) VALUES (?,?,?,?,?,?,?);");
    mysqli_stmt_bind_param( $statment, 'ssssisss', $new_table, $Partner, $Merchant, $ips, $score, $category, $overall, $protocol );
    $statement->execute();
}

最佳答案

对你的问题的简短回答是“不”。

从最严格的意义上来说,在数据库级别,预准备语句只允许将参数绑定(bind)到 SQL 语句的“值”位。

一种思考方式是“可以在语句的运行时执行时替换的东西而不改变其含义”。表名不是这些运行时值之一,因为它确定 SQL 语句本身的有效性(即哪些列名有效),并且在执行时更改它可能会改变 SQL 语句是否有效。

在稍高的级别上,即使在模拟准备好的语句参数替换而不是实际将准备好的语句发送到数据库的数据库接口(interface)中,例如 PDO,它可以想象允许您在任何地方使用占位符(因为占位符在之前被替换)在这些系统中发送到数据库),表占位符的值将是一个字符串,并以字符串形式包含在发送到数据库的 SQL 中,因此 SELECT * FROM ?mytable 因为参数实际上最终会将 SELECT * FROM 'mytable' 发送到数据库,这是无效的 SQL。

你最好的选择就是继续

SELECT * FROM {$mytable}

但是,如果 $mytable 来自用户输入,您绝对应该有一个表白名单,您首先要检查该白名单。

关于php - 我可以在准备好的语句中参数化表名吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28671789/

相关文章:

mysql - 部门薪酬前3名如何选出?

php - WordPress async-upload.php 403 错误

php - 从 Nginx 中的子目录运行辅助 PHP 应用程序

sql - 替换 mySQL 中包含引号的单词时出错

php - 比较文本框和下拉数据库

php - 使用php更新sql数据库

mysql - 基于 3 个表的 Outer Join

php - 允许第 3 方身份验证的 CodeIgniter 身份验证系统?

php - 从数据库中获取尚未建立关系的所有对象

php - 如何在mysql的单列中保存多个图像