Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/262.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用PHP编制语句真的必要吗';那是mysqli吗?_Php_Mysql_Mysqli - Fatal编程技术网

用PHP编制语句真的必要吗';那是mysqli吗?

用PHP编制语句真的必要吗';那是mysqli吗?,php,mysql,mysqli,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 ($r

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

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\u real\u escape\u string()
mysql\u query()
mysql\u fetch\u array()
实例

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

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

  • 我的所有项目都没有性能问题
  • 我对将用户输入转换为预期类型(字符串、整数、浮点等)以及手动转义查询中任何地方使用的任何用户输入非常敏感

  • 考虑到这一点,对于过去或未来的项目,是否真的有必要转换为准备好的报表?

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

    我对将用户输入转换为预期类型(字符串、整数、浮点等)以及手动转义查询中任何地方使用的任何用户输入非常敏感

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

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

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

    尽管我看到另一位斯马特先生提出了他的永久移动电话,感到有些恼火,但我不能说他的想法在某种程度上完全不合理。但不幸的是,它们都是基于错误的假设。

    哪些是

    • 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);
    

    上述内容的可能重复并非完全重复,但仍然涵盖了您的问题。您可以在
    db\u查询
    函数中添加可选的第二个参数;如果它不是空的,则它包含一个带有变量的数组,并且必须准备语句。然后你可以两者都用。但是,这不会使您的sql更安全,您擅长使用
    mysqli\u real\u escape\u string
    (请注意手册中的字符集警告)。谢谢hjpotter92,我阅读了另一个关于性能的问题。同样,也有一些人暗示准备好的语句是安全的,而非准备好的语句是不安全的,我认为如果你正确地清理并避开用户输入,这是不正确的。@MrCarrot:)只要你做得对,一切都是安全的(100%正确),但有时你不这样做,或者你的伴侣不这样做,或者你认为你做得对,但你没有。这就是为什么人们会创造一些东西来帮助你做正确的事情,或者强迫你做正确的事情。您也可以在prepared_语句中出错,但与普通的mysql_查询相比,这种可能性更小,损害也更小?(国际)$_POST['id']:0 ;;但我接受你对错误的评论和/或其他对逃避输入不感兴趣的人的评论。