考虑到每个人总是担心用户数据(并且正确),只要在获得它时简单地遍历每个外部数组就足够了,并应用mysql_real_escape_string()。
我很好奇这是不是一个坏主意。
类似的东西:
function getExternalData($type='GET') { $type = strtoupper($type); $data = $_$type; foreach($data as $key => $value) { $clean[$key] = mysql_real_escape_string($value); } return $clean; }
这将使所有数据在数据库中安全使用。但是,这样做的缺点是什么?
答案 0 :(得分:2)
在所有超全局变量上应用mysql_real_escape_string
会让人觉得你要么在MySQL查询中专门使用它们,要么你不知道mysql_real_escape_string
有什么好处。
答案 1 :(得分:2)
主要的想法是,如果你必须处理输入,例如为了解析标记,你必须取消输入,然后不要忘记重新转义它。而且,这是非常低效的。查询占位符是防止SQL注入的一种非常好的方法。
至于清理本身(不仅适用于SQL),您应该查看Filter extension,默认情况下在PHP 5.2中可用,在PECL中可用于5.1。
答案 2 :(得分:1)
缺点:
您可能会忘记其他类型的用户输入,因此,不要清理它们 而且,当然,多余的循环 并且,我认为数据库清理应该尽可能最新,就在您将数据输入DL中的数据库之前 用于演示的清洁数据应在呈现数据等之前完成。
那就是说,在你尝试这种方法之前,你永远不会知道,因为人们通常不同意他们不使用自己的方法(见上文:-))
答案 3 :(得分:1)
不要尝试清理数据。对占位符使用查询。见bobby-tables.com
答案 4 :(得分:1)
我认为概括验证和过滤逻辑是个坏主意。毕竟这是魔术引号背后的想法,现在普遍受到谴责。
除此之外,验证字段输入通常涉及大量特定垃圾。通用规则只是验证的一小部分,特别是随着应用程序的大小和复杂性的增加。
最好提出一个迷你框架,允许您在同一个地方处理通用和特定验证。像这样......
class BrokenRules extends Exception {
protected $errors;
function __construct($errors) {
$this->errors = $errors;
}
function getErrors() {
return $this->errors;
}
}
class Foo {
protected $db;
function __construct(PDO $db) {
$this->db = $db;
}
function loadNew() {
return array('bar' => 'new foo', 'baz' => 5);
}
function loadById($id) {
$stmt = $this->db->prepare('SELECT * FROM foo WHERE id = ?');
$stmt->bindValue(1, $id, PDO::PARAM::INT);
$stmt->execute();
return $stmt->fetch();
}
function save($data) {
return isset($data['id']) ? $this->update($data) : $this->insert($data);
}
protected function validateForInsert($data) {
if ((int)$data['baz'] <= 3) $errors['baz'][] = 'Baz must be greater than 3';
if (isset($errors)) throw new BrokenRules($errors);
}
protected function validateForUpdate($data) {
// TODO: validateForUpdate
}
protected function insert($data) {
$this->validateForInsert($data);
$stmt = $this->db->prepare('INSERT INTO foo (x, y) VALUES (?, ?)');
$stmt->bindValue(1, $data['bar'], PDO::PARAM_STR);
$stmt->bindValue(2, $data['baz'], PDO::PARAM_INT);
$stmt->execute();
return $this->db->lastInsertId();
}
protected function update($data) {
$this->validateForUpdate($data);
$stmt = $this->db->prepare('UPDATE foo SET x = ?, y = ? WHERE id = ?');
$stmt->bindValue(1, $data['bar'], PDO::PARAM_STR);
$stmt->bindValue(2, $data['baz'], PDO::PARAM_INT);
$stmt->bindValue(3, $data['id'], PDO::PARAM_INT);
$stmt->execute();
return $data['id'];
}
}
try {
$foo = new Foo($pdo);
if ($_POST) {
$id = $foo->save($_POST);
redirect("edit_foo.php?id=$id");
} else if (isset($_GET['id'])) {
$data = $foo->loadById($_GET['id']);
} else {
$data = $foo->loadNew();
}
} catch (BrokenRules $e) {
$errors = $e->getErrors();
}
include 'templates/foo.php';
答案 5 :(得分:0)
我认为你实际上在寻找array_map()。这消除了对循环的需要。是的,这对于为数据库提供安全请求是可以接受的。
但有一点,你可能想在这里使用$_SERVER['REQUEST_METHOD']。 (除非你使用它作为参数传递给这个函数。)