prepare()
对于我的大多数代码来说似乎有点乏味和不必要。如果我在SQL命令中发送一个字符串,为什么我不能用real_escape_string
来清理它?有什么不同?这就是我一直在做的事情,它对SQL注入效果很好......谢谢。
答案 0 :(得分:7)
在SQL注入防御中,转义与使用查询参数一样有效。
如果不能始终如一地执行这两种方法,这两种方法的效果也会降低。
这两种方法仅用于保护SQL表达式中的单个值。它们不支持查询的其他动态部分。例如,如果要ORDER BY用户指定的列。查询参数和转义函数都不能处理。
所以基本上,这是一种风格和个人偏好的问题。
我更喜欢查询参数,因为我认为:
$sql = "INSERT INTO mytable (columna, columnb, columnc) VALUES (?, ?, ?)";
$stmt = $pdo->prepare($sql);
$stmt->execute([$a, $b, $c]);
比这更清楚:
$sql = "INSERT INTO mytable (columna, columnb, columnc) VALUES ('".mysqli_real_escape_string($conn, $a)."', '".mysqli_real_escape_string($conn, $b)."', '".mysqli_real_escape_string($conn, $c)."')";
mysqli_query($conn, $sql);
你不能认真地说,摆弄所有那些开放引号/密切引号和.
字符串连接比使用带有查询参数的prepare()更容易。
重新评论一个带参数的假设query()
函数。
首先,没有必要。一起使用prepare()和execute()是编写安全代码的一个小代价,并且坚持使用单个函数执行它,你只是听起来很懒惰。我想你不检查错误返回false
的函数的返回值吗?
为了它的价值,编写一个包装函数来做这两件事很容易,因为PHP隐式支持varargs。
function myquery() {
global $pdo;
$params = func_get_args();
$sql = array_shift($params);
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
return $stmt; // so we can fetch(), etc.
}