【发布时间】:2013-09-09 22:40:44
【问题描述】:
好吧,我还是不太明白。我一直在阅读,为了正确地转义您的 MySQL 查询,您需要使用 mysqli_prepare() 和 mysqli_bind_param()。
我尝试使用此设置,坦率地说,它有点笨拙。当我不需要再次引用它们时,我被困在通过引用传递变量,而完成相同任务只需更多的代码行。
我想我只是不明白两者之间的区别:
<?php
$sql = new \MySQLi(...);
$result = $sql->query('
UPDATE `table`
SET
`field` = "'.$sql->real_escape_string($_REQUEST[$field]).'";
');
?>
和
<?php
$sql = new \MySQLi(...);
$stmt = $sql->prepare('
UPDATE `table`
SET
`field` = ?;
');
$value = $_REQUEST[$field];
$stmt->bind_param('s', $value);
$stmt->execute();
$result = $stmt->get_result();
unset($value);
?>
除了更多的代码。
我的意思是,他们是否实现了这一点,以便人们在将值发送到查询之前不会忘记转义值?还是它更快?
或者当我打算重复使用同一个查询(因为mysqli_stmt可以重复使用)并在其他情况下使用传统方法时,我应该使用这种方法吗?
【问题讨论】:
-
据我所知,准备好的语句并不是为了防止 sql 注入而设计的,它们只是因为它们的工作方式才这样做。据我了解,它们旨在让您循环查询时听到较少的声音(只有变量随执行一起发送,而不是查询本身)。不过我可能是错的,如果我错了,我很乐意被告知。
-
在第二个示例中更让我“跳出来”的是 SQL 文本中没有 WHERE 子句。这在第二个陈述中更容易发现,在第一个陈述中更加伪装。但是对于第一个示例中的那个变量,包装在
mysqli_real_escape_string函数中,至少我知道 WHERE 子句不在变量中。如果它没有被包装(因为我们看到了太多的例子),我不会知道,看看那个语句,那个变量是否包含 WHERE 子句。
标签: php mysql mysqli prepared-statement mysql-real-escape-string