3

我正在尝试创建一个允许我删除表中某一行的函数。我想将该函数用于几个不同的表,因此当我调用该函数时,我会将函数的参数之一设为表名。这是我正在尝试做的一个例子:

function delete($conn, $table, $id) {
    $stmt = $conn->prepare("DELETE FROM ".$table." WHERE id = :id");
    $stmt->bindParam(":id", $id, PDO::PARAM_INT);
    $stmt->execute();  

    if ($stmt->rowCount() > 0) {
            return true;
    } else {
            return false;
    }
}

我遇到的一个问题是,因为 $table 变量直接进入 SQL 查询,我的数据库不会面临 SQL 注入的风险吗?

正如我从其他一个问题中了解到的那样,我不能只将 :table 添加到 bindParam 函数中,所以我不知道如何使这个函数安全。有任何想法吗??

4

3 回答 3

3

清理表格数据

您可以定义一组列入白名单的表名以在您的函数中使用:

$whitelist = array('table1', 'table2', ...)

然后使用:

$myTable= array_intersect_keys($table, array_flip($whitelist));

$myTable现在将是安全的。

于 2012-11-21T18:12:50.923 回答
0

MySQL 目前不支持动态 SQL 字符串构建,但您可以尝试使用表的白名单或可能使用 PDO 的准备语句(冗余,我知道)的 MySQL 准备语句。

$sql = "
PREPARE stmt FROM 
'DELETE FROM @tbl WHERE id = :id';
EXECUTE stmt USING :table;
";
$stmt = $db->prepare($sql);
$stmt->bindParam(':id', $id, PDO::PARAM_INT);
$stmt->bindParam(':table', $table);

这是未经测试的,但可能会有所帮助。

于 2012-11-21T18:15:41.123 回答
0

作为元数据的表名比行数据更受限制 - 因此清理表名应该比清理数据更可靠。我当然指的是在 PDO 之外进行消毒。

我们经常使用的是一个 PHP 包含,它包含所有有效的表名作为数组定义,所以我们只是查找它 - 如果找不到,并且包含的​​文件年龄超过一个小时,我们运行“ SHOW TABLES”并重新创建包含,因此它非常自动化。

于 2012-11-21T18:14:15.740 回答