【问题标题】:Changing from mysqli to pdo从 mysqli 更改为 pdo
【发布时间】:2018-02-07 12:23:00
【问题描述】:

我对这段代码没有任何问题,它运行得非常好,但我真的不明白它是如何工作的,甚至是正确的,所以:

我对 mysqli 的 ajax post 或 get 调用查询如下:

$con = mysqli_connect('localhost','root','','db') or die(header('Location: ./404.php'));
$add = "INSERT INTO table (id, id2, id3) VALUES('','$fid','')";
            if(mysqli_query($con, $add)){
                echo "added";
                }
$remove = "DELETE FROM table WHERE id2='$fid'";
            if(mysqli_query($con, $remove)){
                echo "removed";
            }
$getInfo = "SELECT * FROM table";
            $result = $con->query($getInfo);
            if($result->num_rows > 0) {
                while($row = $result->fetch_assoc()){
                   //do something
                } 
            }

对于$_POST or $_GET values I used mysqli_real_escape_string

这里转换为PDO:

try{
$con = new PDO('mysql:host=localhost;dbname=db;charset=utf8mb4', 'root', '', array(PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));

$get = $con->query("SELECT * FROM table");
    foreach($get->fetchAll(PDO::FETCH_ASSOC) as $row){
                    $data['0'] = $row['name'];
                    $data['1'] = $row['email'];
                    return $data;
                }

$add = $con->prepare("INSERT INTO table (id, id2, id3) VALUES(:f1,:f2,:f3)");
            $add->execute(array(':f1' => '', ':f2' => $fid, ':f3' => ''));
            echo "added";

$remove = $con->prepare("DELETE FROM table WHERE id2=:f1");
            $remove->bindValue(':f1', $fid, PDO::PARAM_STR);
            $remove->execute();
                echo "removed";

}catch(PDOException $ex){
    echo "error";
}

现在这可行,但我真的不知道它是否用 pdo 正确编写,我不需要将 mysqli_real_escape_string 与 mysqli 或类似的东西一起使用。 我在网上能找到的只是它现在是如何编写的,代码的哪一部分在做什么,例如,当我在 mysqli 中使用插入、更新或删除时,我使用了

if(mysqli_query($con, $sql)){echo "success";}else echo 'fail';

如何使用 pdo 做到这一点? 而且对于使用 try 和 catch,我不知道我是否需要对每个查询都使用它,还是像我上面添加的那样?

再说一遍,我是 pdo 的新手,我不太了解它,上面的代码可以工作,但我不知道它的编写方式是否正确?

【问题讨论】:

  • 给你我的朋友:phpdelusions.net/pdo
  • @gview 谢谢,有人在没有解释的情况下否决了下面的答案,你能不能给一个他的答案错误的原因?
  • 为您提供了详细的解答,希望对您有所帮助。另外,我非常怀疑你的句柄是否准确——你显然根本不是一个愚蠢的孩子;)
  • 我不知道我是否真的很愚蠢,但我总是有问题已经存在于某个地方,但我每次都以错误的方式搜索它们,所以当我问一些问题时,它可能听起来很愚蠢,就像我会问为什么我有 PDO::FETCH_ASSOC 以及为什么我们需要:: 但不需要: 或 ::::::。你明白了,如果我想知道某件事是如何工作的,我需要知道每一个细节......
  • 顺便说一句,感谢您的链接和您的回答,它有很大帮助!

标签: php mysqli pdo


【解决方案1】:

首先,让我祝贺您选择 PDO。在我认识的所有经验丰富的 PHP 开发人员中,几乎一致认为他们更喜欢 PDO 而不是 mysqli。

我强烈推荐您read through this guide 使用 PDO。它应该可以回答您的所有问题,甚至可以回答您将来可能遇到的一些问题。

针对您的具体问题:

不,您不再需要转义任何内容,只要您使用带有占位符的准备好的语句。转义的存在正是因为人们将变量插入到 SQL 语句中,这可能会混淆您需要包含字符串的引用。

使用准备好的语句,问题不再存在,这也意味着不再存在 SQL 注入的危险。 SQL 注入利用字符串连接将原始 SQL 语句转换为完全不同的语句,再次使用引号,这就是为什么从用户输入接受的非转义字符串是 SQL 注入的攻击向量的原因。这两个问题都可以使用参数和预处理语句来解决。

至于 PDO 的错误处理,您想使用 PDO::ERRMODE_EXCEPTION 讨论的 in the manual here

不幸的是,PDO 的默认值是PDO::ERRMODE_SILENT,它基本上忽略了数据库错误,只是设置了您必须自己检查的 PDO 对象变量。

话虽如此,您可以通过在创建 PDO 连接对象时或之后添加错误模式来解决此问题。示例在我链接的 PDO 错误模式页面上。

对于 Try-Catch 块,一般来说,除非您有一些功能代码来解决错误,否则您不想专门捕获异常。包装每个 sql 调用只是为了报告错误消息是不好的,无论是从 DRY 的角度来看,还是作为一种反模式。使用正确的错误模式,SQL 错误将引发您可以在错误处理程序中处理的异常,并且通常是您不应该吃掉并继续处理的事情。

您的错误处理程序应该(在生产中)将错误记录到磁盘/通过电子邮件发送给系统管理员或站点所有者,并显示专业外观的非特定错误消息,通知用户问题并且应该发生在所有异常中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-29
    • 2019-09-04
    • 1970-01-01
    • 2014-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多