使用PHP的mysqli是否真的需要PREPARE语句?

时间:2013-09-12 01:10:10

标签: php mysql mysqli

目前我有一些数据库包装函数,如下所示:

function db_escape($str) {
    return mysql_real_escape_string($str);
}

function db_query($sql) {
    global $LINKID;
    return mysql_query ($sql, $LINKID);
}

function db_fetch_array($result) {
    return mysql_fetch_array ($result, MYSQL_ASSOC);
}

在我的代码中,我可以执行以下操作:

$result = db_query('SELECT userid, first_name, last_name FROM user 
                    WHERE email = "' . db_escape($email) . '"');

if ($result) {
    $user = db_fetch_array($result);
}

这背后的一个想法是,当我从mysql切换到mysqli时,只需几分钟即可更新我的包装函数,而且我不必替换数百个mysql_real_escape_string()的实例,数百个不同的项目mysql_query()mysql_fetch_array()

唯一的问题是,上面的内容可以很容易地转换为标准的过程mysqli函数,但不是准备好的语句。

这有关系吗?似乎每个教程都说准备好的语句对于安全性和性能很重要,但是目前:

  1. 我的项目都没有性能问题。
  2. 我非常擅长将用户输入转换为预期类型(字符串,整数,浮点数等),并且还可以手动转义在查询中任何位置使用的任何用户输入。
  3. 考虑到这一点,是否真的有必要切换到过去或未来项目的准备好的陈述?

2 个答案:

答案 0 :(得分:2)

我认为你应该考虑长远的利益。例如,如果您将来不再是该项目的开发人员,那么使用未准备好的语句的习惯将传递给下一个开发人员并且:

  

我非常擅长将用户输入转换为期望的类型(字符串,整数,浮点数等),并且还手动转义在查询中任何位置使用的任何用户输入。

可能不再适用。即使你说你非常小心,在某些时候你会犯错误或遗忘(是的,人们做了!这就是事情破裂的原因)那么这将是一个问题。

以下面的案例为例。你认为这样安全吗?

$id = $_POST['id'];
$result = db_query('SELECT userid, first_name, last_name FROM user 
                WHERE userid = ' . db_escape($id) );

答案 1 :(得分:0)

虽然看到另一位Smart先生想出了他的 Perpetuum Mobile ,我感到有些恼火,但我不能在某种程度上称他的想法完全不合理。但不幸的是,它们都基于错误的假设。

哪些是

  • SQL格式规则仅限于转义和转换
  • 不需要SQL注入的任何保护
  • 此类保护应适用于用户输入
  • 每个PHP应用程序都很小且可观察
  • 就像在另一个答案中提到的那样,只有一个开发人员,他将所有代码保留在他的脑海中,一直在项目上工作。

但同样,所有这些假设都是错误的。

只要您重新考虑它们,您就会得出结论,只有参数化查询可以为您提供保险单。请注意,我说的是使用参数的一般概念,而不是mysqli中使用的特定实现。即使使用旧的mysql ext也可以实现这个想法。

另一件需要考虑的事情是代码美感和尺寸。看看你现在拥有什么

$result = db_query('SELECT userid, first_name, last_name FROM user 
                    WHERE email = "' . db_escape($email) . '"');
if ($result) {
    $user = db_fetch_array($result);
}

以及它可以使用参数

$sql = 'SELECT userid, first_name, last_name FROM user WHERE email = ?';
$user = db_fetch_array($sql, $email);