从mysqli变为pdo

时间:2017-08-29 22:47:04

标签: php mysqli pdo

我对这段代码没有任何问题,令人惊讶地工作正常,但我真的不明白它是如何工作的,甚至是正确的,所以:

我使用mysqli查询ajax帖子或获取电话是这样的:

$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那样使用mysqli_real_escape_string之类的东西。 我在网上找到的就是现在如何编写代码的哪一部分正在做什么,例如我在mysqli中使用插入,更新或删除时使用

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

我怎么能用pdo做到这一点? 而且对于使用try和catch我不知道我是否需要在每个查询中使用它或者我在上面添加它?

再说一次我是pdo的新手,我不太了解它并且上面的代码有效,但我不知道是不是以正确的方式编写了?

1 个答案:

答案 0 :(得分:1)

首先,我要祝贺你加入PDO。在我认识的所有经验丰富的PHP开发人员中,他们一致认为PDO更喜欢mysqli。

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

针对您的具体问题:

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

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

对于使用PDO的错误处理,您希望使用in the manual here讨论的PDO::ERRMODE_EXCEPTION

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

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

对于Try-Catch块,一般情况下,除非您有一些功能代码来解决错误,否则您不希望特别捕获异常。从DRY和反模式的角度来看,包装每个sql调用只是为了报告错误信息是不好的。使用正确的错误模式,SQL错误将抛出您可以在错误处理程序中处理的异常,并且通常是您不应该吃东西并继续进行的事情。

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