• PDO vs. MySQLi 选择哪一个?(PDO vs. MySQLi: Which Should You Use?)-转载


    用Php访问数据的时候,你选择MySQLi和PDO,在选择之前,你应该知道些什么呢?

    这篇文章将会介绍这两种方式的不同点,数据库的支持、稳定性、性能等问题。

    概述

      PDO MySQLi
    Database support 12 different drivers MySQL only
    API OOP OOP + procedural
    Connection Easy Easy
    Named parameters Yes No
    Object mapping Yes Yes
    Prepared statements 
    (client side)
    Yes No
    Performance Fast Fast
    Stored procedures Yes Yes

    链接

    下面是两种连接数据库的方式

    [php] view plaincopy
     
     
    1. // PDO  
    2. $pdo = new PDO("mysql:host=localhost;dbname=database", 'username', 'password');  
    3.    
    4. // mysqli, procedural way  
    5. $mysqli = mysqli_connect('localhost','username','password','database');  
    6.    
    7. // mysqli, object oriented way  
    8. $mysqli = new mysqli('localhost','username','password','database');  


    (请注意,这两个连接将贯穿全文)

    API支持

    PDO和MySQLi都提供了面向对象的API,但是MySQLi也提供了面向过程编程的API(就是函数式)所以对于新手非常易于理解,如果你使用原始的MySQL的API,那么迁移到MySQLi也非常容易。另一方面,一旦你选择了PDO,你就可以用在任何你想要使用的数据库上。

    数据库支持

    PDO比MySQLi的核心优势在于数据库的驱动支持上。再写这篇文章的时候,PDO支持12种数据库驱动,而MySQLi只支持MySQL。

    通过下面的代码可以打印出当前PDO支持的数据库驱动

    [php] view plaincopy
     
     
    1. var_dump(PDO::getAvailableDrivers());  

    这意味着什么?

    如果你选择了使用PDO的方式,当需要换数据库的时候,遇到不存在或者不支持的方法,你只需要更改连接字符串,以及一些查询语句即可,而MySQLi,则需要重新所有的查询以及连接方式。

    名称式参数

    这是PDO具有的一个非常重要的特性,采用名称式参数比数字式参数更加容易。

    [php] view plaincopy
     
     
    1. $params = array(':username' => 'test', ':email' => $mail, ':last_login' => time() - 3600);  
    2.    
    3. $pdo->prepare('  
    4.    SELECT * FROM users  
    5.    WHERE username = :username  
    6.    AND email = :email  
    7.    AND last_login > :last_login');  
    8.    
    9. $pdo->execute($params);  


    而MySQLi的方式:

    [php] view plaincopy
     
     
    1. $query = $mysqli->prepare('  
    2.    SELECT * FROM users  
    3.    WHERE username = ?  
    4.    AND email = ?  
    5.    AND last_login > ?');  
    6.    
    7. $query->bind_param('sss', 'test', $mail, time() - 3600);  
    8. $query->execute();  


    这个问号(?)绑定参数看上去很短,但是相比名称式参数缺少了灵活性,而且迫使开发者必须保证参数的顺序,有时候让人觉得很蛋疼。

    而且不幸的是MySQLi并不支持名称式参数。

    对象映射

    PDO和MySQLi都可以将结果映射成对象。下面自定义一个User类和一些属性,并且字段和数据库的表字段对应。

    [php] view plaincopy
     
     
    1. class User {  
    2.    public $id;  
    3.    public $first_name;  
    4.    public $last_name;  
    5.    
    6.    public function info()  
    7.    {  
    8.       return '#'.$this->id.': '.$this->first_name.' '.$this->last_name;  
    9.    }  
    10. }  


    如果没有用对象映射,如果在使用inof()方法前,就要手工的给属性赋值,或者在初始化的时候赋值。

    而采用对象映射就可以直接完成

    [php] view plaincopy
     
     
    1. $query = "SELECT id, first_name, last_name FROM users";  
    2.    
    3. // PDO  
    4. $result = $pdo->query($query);  
    5. $result->setFetchMode(PDO::FETCH_CLASS, 'User');  
    6.    
    7. while ($user = $result->fetch()) {  
    8.    echo $user->info()." ";  
    9. }  
    10. // MySQLI, procedural way  
    11. if ($result = mysqli_query($mysqli, $query)) {  
    12.    while ($user = mysqli_fetch_object($result, 'User')) {  
    13.       echo $user->info()." ";  
    14.    }  
    15. }  
    16. // MySQLi, object oriented way  
    17. if ($result = $mysqli->query($query)) {  
    18.    while ($user = $result->fetch_object('User')) {  
    19.       echo $user->info()." ";  
    20.    }  
    21. }  


    安全问题

    最常见的当然是SQL注入了。而这两种连接数据的方式都提供了安全机制。

    下面是一个简单通过$_GET方式注入的语句

    [php] view plaincopy
     
     
    1. $_GET['username'] = "'; DELETE FROM users; /*"  


    如果我们不对这个参数进行处理,则问题是显而易见的。而且PDO和MySQLi都支持多重查询。这样可能导致若干数据被删除掉。

    对$_GET数据处理

    [php] view plaincopy
     
     
    1. // PDO, "manual" escaping  
    2. $username = PDO::quote($_GET['username']);  
    3.    
    4. $pdo->query("SELECT * FROM users WHERE username = $username");  
    5.    
    6. // mysqli, "manual" escaping  
    7. $username = mysqli_real_escape_string($_GET['username']);  
    8.    
    9. $mysqli->query("SELECT * FROM users WHERE username = '$username'");  


    从上面的代码可以看出,PDO::quote不仅转义了字符串,而且还加了单引号,而MySQLi只是转义了字符串,需要自己手动加单引号。

    下面是prepared statements的方式查询

    [php] view plaincopy
     
     
    1. // PDO, prepared statement  
    2. $pdo->prepare('SELECT * FROM users WHERE username = :username');  
    3. $pdo->execute(array(':username' => $_GET['username']));  
    4.    
    5. // mysqli, prepared statements  
    6. $query = $mysqli->prepare('SELECT * FROM users WHERE username = ?');  
    7. $query->bind_param('s', $_GET['username']);  
    8. $query->execute();  


    推荐采用prepared statements的方式绑定查询来代替PDO::quote() 和 mysqli_real_escape_string().

    性能

    PDO和MySQLi都有非常好的性能。在非prepared statements的基准测试下,MySQLi略快2.5%,而prepared statements下是6.5%,可以说对于性能无关紧要。如果你真的非常介意这一点点性能的话,而自带的MySQL扩展比两者都快,你可以考虑下它。

    总结

    最后,综合情况PDO在这场对比中胜出,支持12种不同数据库驱动程序(18种不同的数据库)和………………为以上提到的……

    所以结论就是:如果你现在还在使用MySQLi,你可以考虑换了。

    原文链接地址参考:

    http://net.tutsplus.com/tutorials/php/pdo-vs-mysqli-which-should-you-use/

  • 相关阅读:
    github not authorized eclipse 关于 代码不能提交到GitHub
    idea 导入项目后 有的项目目录结构不展开解决办法
    intellij idea 主题大全,看不惯idea 那2种主题的来这里了
    win10 系统输入法与 idea的 ctr+shift+f 快捷键冲突,解决办法
    此地址使用了一个通常用于网络浏览以外目的的端口。出于安全原因,Firefox 取消了该请求。
    关于IntelliJ IDEA有时候快捷键无效的说明
    杜恩德是谁?
    oracle如何连接别人的数据库,需要在本地添加一些配置
    2.6---找有环链表的开头结点(CC150)
    2.3---删除链表的结点,不提供头结点(CC150)
  • 原文地址:https://www.cnblogs.com/huangzelin/p/4619574.html
Copyright © 2020-2023  润新知