我一直在研究PDO bindValue().我知道用PDO准备我的SQL语句会阻止SQL注入的发生.
代码示例:
$stmt = $dbh->prepare('SELECT * FROM articles WHERE id = :id AND title = :title');
$stmt->bindValue(':id', PDO::PARAM_INT);
$stmt->bindValue(':title', PDO::PARAM_STR);
$stmt->execute();
Run Code Online (Sandbox Code Playgroud)
通过将ID绑定为数字,并且Title是一个字符串,我们可以限制当有人尝试在代码中执行SQL注入时所造成的损害.
我们是否应该始终将我们的值绑定在一起,PDO::PARAM_以便我们可以限制SQL注入中可以从数据库中提取的内容?这样做是否会增加PDO的安全性bindValue()?
dec*_*eze 10
你绝对应该使用prepareAPI并从查询中单独传递值,而不是进行普通的字符串插值(例如"SELECT * FROM foo WHERE bar = '$baz'"→ bad).
对于绑定参数,您有三个选项:
你使用它们中的哪一个并不重要,它们都同样安全.有关差异的一些详细信息,请参阅以下答案:
使用bindParam或时bindValue,传递第三个PDO::PARAM_参数类型是可选的.如果未传递,则默认将参数绑定为字符串.这意味着你最终可能会得到一个等同于... WHERE foo = '42'而不是的查询... WHERE foo = 42.这取决于您的数据库如何处理它.MySQL将根据需要自动将字符串转换为数字,就像PHP一样(例如'42' + 1).其他数据库可能对类型更加挑剔.
同样,所有选项都同样安全.如果你想一个字符串绑定'foo'使用PDO::PARAM_INT,该字符串将被强制转换为整数,因此必然作为值0.注射不可能.
You*_*nse 10
一个问题有两个.至关重要的是不要混淆它们
而对于第二个,为了代码的健全和干燥 -
有许多方法可以避免手动绑定.他们之中有一些是:
ORM是简单CRUD操作的绝佳解决方案,必须在现代应用程序中使用.它将完全隐藏SQL,在幕后进行绑定:
$user = User::model()->findByPk($id);
Run Code Online (Sandbox Code Playgroud)查询生成器也是一种方法,在一些PHP运算符中伪装SQL,但再次隐藏在幕后的绑定:
$user = $db->select('*')->from('users')->where('id = ?', $id)->fetch();
Run Code Online (Sandbox Code Playgroud)一些抽象库可以通过类型提示占位符来处理传递的数据,再次隐藏实际的绑定:
$user = $db->getRow("SELECT * FROM users WHERE id =?i", $id);
Run Code Online (Sandbox Code Playgroud)如果你仍然在上个世纪的方式使用PHP,并且在整个代码中都有原始的PDO - 那么你可以在execute()中传递你的变量,仍然可以节省很多自己的输入:
$stmt = $dbh->prepare('SELECT * FROM users WHERE id = ?');
$stmt->execute([$id]);
$user = $stmt->fetch();
Run Code Online (Sandbox Code Playgroud)从第三个问题开始 - 只要你将数字绑定为字符串(但不是相反!) -
因为mysql总是将您的数据转换为正确的类型.我知道的唯一情况是LIMIT子句,您不能将数字格式化为字符串 - 因此,唯一相关的情况是在仿真模式下设置PDO并且您必须在LIMIT子句中传递参数时.在所有其他情况下,您可以省略第三个参数,以及显式调用bindValue()没有任何问题.
| 归档时间: |
|
| 查看次数: |
1335 次 |
| 最近记录: |