现在,假设这 4 个变量是用户输入的,我不明白这如何防止 SQL 注入。据我了解,他们仍然可以在其中输入任何他们想要的内容。
主要原则是使用准备好的语句,该语句旨在将安全查询发送到数据库服务器,这可以通过转义不属于实际查询的用户输入来完成,并且还检查没有任何(where 子句)的查询以检查使用任何参数之前查询的有效性。
从这个问题:PDO 向 MySQL 发送原始查询,而 Mysqli 发送准备好的查询,两者都产生相同的结果
$stmt = $mysqli->prepare("SELECT * FROM users WHERE username =?")) {
$stmt->bind_param("i", $user);
$user = "''1''";
服务器日志:
130802 23:39:39 175 Connect ****@localhost on testdb
175 Prepare SELECT * FROM users WHERE username =?
175 Execute SELECT * FROM users WHERE username =0
175 Quit
通过使用prepared statement,db server会检查没有任何参数的查询,在这个阶段,可以在绑定任何参数之前检测到错误,然后,如果查询有效,也会将参数发送到服务器以完成查询。
来自 PHP 手册http://php.net/manual/en/mysqli.quickstart.prepared-statements.php:
转义和 SQL 注入
绑定变量将被服务器自动转义。服务器在执行之前将它们的转义值插入到语句模板的适当位置。必须向服务器提供绑定变量类型的提示,以创建适当的转换。有关详细信息,请参阅 mysqli_stmt_bind_param() 函数。
..
我也找不到那里的“sssd”的解释。它有什么作用?这就是让它更安全的原因吗?
答案在这里: http: //php.net/manual/en/mysqli-stmt.bind-param.php
i
corresponding variable has type integer
d
corresponding variable has type double
s
corresponding variable has type string
b
corresponding variable is a blob and will be sent in packets
最后一个问题:我在另一个问题上读到 mysqli_real_escape_string 已被弃用,但手册中并没有这么说。它是如何被弃用的?由于某种原因,它不能再转义特殊字符了吗?
能给个参考吗?我想你误解了 ( mysql_real_escape_string()
)