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/35582816/

相关文章:

php - 获取整行的单选值到下一个文件

c# - 如何从 MVC Razor 中的两个表返回带有外部连接的 View

php - Ajax:区分旧帖子和新帖子

C# MySQL - 2 个查询之间的差异

php - 将 latin1 转换为 UTF8

javascript - Angular JS HTTP Post 不起作用

javascript - JDBC - MySQL 调用存储过程

MySQL错误1111(HY000): Invalid use of group function

sql - 数据库中的营业时间使用什么数据类型

php - 一列中有多个外键?