【问题标题】:When to use prepared statements?什么时候使用准备好的语句?
【发布时间】:2013-01-26 08:48:17
【问题描述】:

我有几个问题。

规范:MySql 数据库;服务器端语言 PHP 5.3.10

1) 什么时候应该使用准备好的语句?

我正在构建一个有用户的 web 应用程序。我不断地在数据库中检索/插入数据。我目前没有使用准备好的语句,我想知道这是否是错误的做事方式?

/**
     * Register a new user into the database.  Please make sure to
     * hash the password.
     * @param type $fName First name of the user - String value.
     * @param type $lName Last name of the user - String value.
     * @param type $email Email address of the user - String value.
     * @param type $hashedPassword - String value.
     * @return boolean true if sucessful or false if failed.
     */
    function registerUser($fName, $lName, $email, $hashedPassword)
    {
        //Establish a connection.
        $mysqli = new $mysqli($GLOBALS['dbServer'], $GLOBALS['dbUserName'], $GLOBALS['dbPassword'], $GLOBALS['dbName']);

        //Check if connection failed.
        if($mysqli->connect_error)
        {
            die('Connect Error (' .$mysqli->connect_errno . ') '
                    .$mysqli->connect_error);
        }

        //Insert data into the table and check if the attempt was sucessful.
        if($mysqli->query("INSERT INTO user_info(email, password, fName, lName) VALUE  ('$email', '$hashedPassword', '$fName', '$lName')"))
        {
            return true;
        }
        return false;            
    }

这是将值插入数据库并确保它成功的正确方法吗?或者,我可以使用准备好的语句,我想知道

2) 我将如何使用准备好的语句?我为什么要(如果你建议我这样做)?

我预计该网站每天的访问量约为 20,000 次。或者让我们假设有多少......

【问题讨论】:

  • 没有冒犯,但这个问题(“我为什么要”)已经被问过数千次了。为什么不先搜索一下? for exapmle

标签: php mysql mysqli prepared-statement web-traffic


【解决方案1】:

您应该始终使用准备好的语句。这将防止任何 SQL 注入的机会(前提是准备工作正确)。我猜您还想知道何时可以使用常规查询来提高效率;硬件总是可以升级的。注意二阶 SQL 注入 (example)。

【讨论】:

  • 感谢您的链接。我阅读了这篇文章,目前我正在这样做。我有一个防止 XSS 和 SQL 注入的功能,但正如文章指出的那样,这不是最好的方法。
【解决方案2】:

除了“我为什么要”这个问题which has been answered already,你的代码中还有一些地方需要更正。

  1. 在每个函数中创建新的数据库连接是不可行的。
    在引导文件的某处创建一次,然后使用 global 关键字访问它。
  2. 死在代码中间是另一个禁忌。
  3. 将许多运算符塞入一行并没有好处,但会使代码难以阅读和支持。
  4. 与 PDO 不同,Mysqli 无法帮助减少代码中的重复,因此,程序员必须小心。

所以,这个函数会是这样的

function registerUser($fName, $lName, $email, $hashedPassword)
{
    global $mysqli;

    //Insert data into the table and check if the attempt was sucessful.
    $sql = "INSERT INTO user_info(email, password, fName, lName) VALUES (?,?,?,?)";
    $sth = $mysqli->prepare($sql);
    foreach (func_get_args() as $i => $value) {
        $sth->bindValue($i+1, $value, PDO::PARAM_STR);
    }
    $mysqli->execute();
    return !$mysqli->error;
}

【讨论】:

  • 我不熟悉管理连接。有推荐的教程吗?我也会自己在网上搜索,但想知道您是否有任何建议。在上面的示例中,该连接何时/何地关闭?如果我不在正在使用的函数中打开并关闭它,我最终不会有很多连接吗?
最近更新 更多