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

转载 2013年12月12日 09:32:43

本文并非直译

用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
链接

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

  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支持的数据库驱动

  1. var_dump(PDO::getAvailableDrivers());  

这意味着什么?

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

名称式参数

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

  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的方式:

  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类和一些属性,并且字段和数据库的表字段对应。

  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()方法前,就要手工的给属性赋值,或者在初始化的时候赋值。

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

  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()."\n";  
  9. }  
  10. // MySQLI, procedural way  
  11. if ($result = mysqli_query($mysqli$query)) {  
  12.    while ($user = mysqli_fetch_object($result'User')) {  
  13.       echo $user->info()."\n";  
  14.    }  
  15. }  
  16. // MySQLi, object oriented way  
  17. if ($result = $mysqli->query($query)) {  
  18.    while ($user = $result->fetch_object('User')) {  
  19.       echo $user->info()."\n";  
  20.    }  
  21. }  

安全问题


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

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

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

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

对$_GET数据处理

  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的方式查询

  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/

相关文章推荐

PHP中MySQL、MySQLi和PDO的用法和区别

PHP的MySQL扩展(优缺点) 设计开发允许PHP应用与MySQL数据库交互的早期扩展。mysql扩展提供了一个面向过程 的接口; 并且是针对MySQL4.1.3或更早版本设计的。因此,...

mysql,mysqli和PDO的区别

一、php手册关于mysql的说明:      This extension is not recommended for writing new code. Instead, either th...

简要谈谈php中mysql,mysqli,mysqlnd,pdo到底是什么.

名词解释:最开始的初学者,往往搞不清mysqli,mysqlnd,pdo到底是什么,下面先直接贴出最直观的名字吧。 MYSQL:This extension is deprecated as of...

php mysql数据库操作mysql和pdo的实现

最近在项目中用到了pdo,之前一直用的mysql类,查了查手册,发现功能大同小异,于是我用接口封装了一个pdo类,实现了与mysql 的相同实现。 大概用到了:单例模型,接口,静态方法,mvc 第...

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

本文并非直译 用Php访问数据的时候,你选择MySQLi和PDO,在选择之前,你应该知道些什么呢? 这篇文章将会介绍这两种方式的不同点,数据库的支持、稳定性、性能等问题。 概述 ...
  • treesky
  • treesky
  • 2012年02月23日 11:33
  • 5958

PDO vs MySQLi( MySQL升级版 )

本文并非直译 用Php访问数据的时候,你选择MySQLi和PDO,在选择之前,你应该知道些什么呢? 这篇文章将会介绍这两种方式的不同点,数据库的支持、稳定性、性能等问题。 ...

单独编译安装php的mysqli,pdo_mysql,mysqlnd扩展

首先安装mysqli扩展 cd /usr/local/src/php-7.17/ext/ cd mysqli /usr/local/php/bin/phpize ./configur...

zhphp framework (十二) 数据链接层,首先pdo,其次mysqli,再次mysql接口

淺談 PHP-MySQL, PHP-MySQLi, PDO 的差異

PHP-MySQL 是 PHP 操作 MySQL 資料庫最原始的 Extension ,PHP-MySQLi 的 i 代表 Improvement ,提更了相對進階的功能,就 Extension 而言...

PHP连接到mysql的方法--mysqli和PDO

php连接到mysql数据库,经典的方式就是使用mysql_connect(),具体代码如下:
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:PDO vs. MySQLi 选择哪一个?(PDO vs. MySQLi: Which Should You Use?)
举报原因:
原因补充:

(最多只允许输入30个字)