如果我们使用php mysqli或PDO包装器类,它们是否会阻止SQL注入风险?
E.g。
https://github.com/ezSQL/ezSQL
或
https://github.com/bennettstone/simple-mysqli
始终使用所有专家建议使用预准备语句和参数化查询。
包装器类对于在快速时间内进行较少编码非常有用,并且还有助于减少重复编码。
那么我们如何同时使用包装类以及预处理语句和参数化查询?
我对此感到困惑?
e.g。
示例来自 - How can I prevent SQL injection in PHP?
使用预准备语句和参数化查询
$stmt = $dbConnection->prepare('SELECT * FROM employees WHERE name = ?');
$stmt->bind_param('s', $name);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
// do something with $row
}
使用包装类,例如我们用它作为
$name = $database->filter($_POST['name']);
$query = $database->get_results("select* from employee where name='$name'");
foreach ($query as $row){
// do something with $row
}
然后在哪里使用包装器以及在哪里使用预准备语句?
如何同时使用两者?
如何在使用包装类时实现sql注入?
答案 0 :(得分:0)
将参数化与包装类结合起来就像是让你的包装器的get_results()
方法采用可选的参数数组:
get_results($sql, array $params = null)
然后该函数的代码将bind_param()
与数组一起使用。但这是Mysqli的痛苦,因为bind_param()
需要varargs。它很丑。您必须将数组转换为引用数组,然后使用call_user_func_array()
将数组作为varargs传递给mysqli的bind_param()
。
我在这里有一个解决方案:https://stackoverflow.com/a/7383439/20860
但我建议你改用PDO。这项任务要容易得多,因为你可以将你的参数数组传递给PDOStatement::execute()。
这样的事情:
class MyDatabaseWrapper {
protected $pdo;
...
public function get_results($sql, array $params=null) {
$stmt = $this->pdo->prepare($sql);
$stmt->execute($params);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
}
答案 1 :(得分:0)
答案很简单:一个好的包装类总是允许你使用预准备语句。否则只是不要使用它。
然后在哪里使用包装器以及在哪里使用预准备语句?
始终
如何同时使用两者?
只需使用它们。
如何在使用包装类时实现sql注入?
使用包装类提供的预准备语句。
这意味着到目前为止你设法找到的两个过时的包装器都不应该被使用。还有其他包装为您提供简单和安全。
例如,我有一个very simple PDO wrapper。由于PDO已经是一个包装器,它只是几行,为您提供了大量的自动化开箱即用。
它使您的代码比您提到的那些失败的包装器更简单:
$query = $database->run("select* from employee where name=?", [$_POST['name']]);
foreach ($query as $row){
// do something with $row
}