到目前为止,根据我的理解,将用户输入插入数据库的风险是 sql 注入(inject),女巫准备好的语句会处理,并且根据我的阅读,在将数据保存到数据库之前不应更改数据,如 htmlspecialchars()
当在页面上回显来自数据库的用户输入时,应该始终使用它。
例如,如果我有这样的查询:
$var1 = $_POST['userInput1'];
$var1 = $_POST['userInput2'];
$stmt = $db->prepare("INSERT INTO tableName (Column1, Column2) VALUES (?, ?)");
$stmt->bindParam(1, $var1);
$stmt->bindParam(2, $var2);
$stmt->execute();
撇开验证不谈,还有什么需要对这个变量做的吗?或者从现在开始,用户输入的任何内容都是安全的并且可以存储?
另外,我应该使用命名占位符而不是位置占位符,还是这只是一种优惠?
最佳答案
在将变量用作准备好的语句的参数之前,您无需对变量执行任何操作。
事实上,您绝不能执行任何转义字符串或引号或其他任何操作,因为反斜杠或其他任何内容都会按字面意义插入到您的数据库中。
您可能还喜欢 PDO 更简单的用法。您不需要使用 bindParam(),您只需将一个值数组传递给 execute() 即可:
$stmt = $db->prepare("INSERT INTO tableName (Column1, Column2) VALUES (?, ?)");
$stmt->execute([$var1, $var2]);
关于您关于命名参数占位符的问题:
没有什么区别,只是帮助你写出更具可读性的代码而已。您仍然可以使用传递值数组的简短形式:
$stmt = $db->prepare("INSERT INTO tableName (Column1, Column2) VALUES (:col1, :col2)");
$stmt->execute(['col1'=>$var1, 'col2'=>$var2]);
如果您已经有一个带有正确键/值对的散列数组(例如您的 $_POST
数组),它会特别方便。很想做以下事情:
$stmt = $db->prepare("INSERT INTO tableName (Column1, Column2) VALUES (:userInput1, :userInput2)");
$stmt->execute($_POST);
但是要小心这一点,因为您不能假设 $_POST
只有您需要的字段。如果您向 PDO 传递一个包含太多字段的数组,或者其键名与您的参数占位符不匹配的字段,PDO 将抛出错误。因此,任何人都可以提出会导致您的应用出错的请求。
关于php - 在将用户输入插入数据库之前,除了准备好的语句之外还有什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48932931/