Keep on going, never give up.

PDO和MySQLi连接区别

自PHP5.5开始,传统的mysql扩展已经废弃,只能使用PHP提供的MySQLi扩展或PDO扩展,从mysql传统接口移植到这两种接口,改动工作都不小,尤其是使用pdo接口,基本大部分访问语句都需要重写,没办法谁让新扩展更安全更高效呢。那么它们之间的区别有哪些呢?本文汇总此两种连接的各自特点,主要从数据库支持、稳定性及性能等方面做个简单比较,仅供设计参考。

MySQL PDO连接实例

PDO query和execute区别

申明:本文翻译来源于文本链接地址,天缘在该文基础上稍作补充修整,如有不明之处,请直接访问文末原文链接。

一、PDO和MySQLi区别

下表列出PDO和MySQLi的几个典型方面区别:

更多方面比较也可参考另一篇文章:

http://www.php.net/manual/zh/mysqlinfo.api.choosing.php

二、连接方式

PDO和mysqli创建连接方式如下:

// PDO
$pdo = new PDO("mysql:host=localhost;dbname=database", 'username', 'password');
 
// mysqli, procedural way
$mysqli = mysqli_connect('localhost','username','password','database');
 
// mysqli, object oriented way
$mysqli = new mysqli('localhost','username','password','database');

三、API和数据库

PDO和MySQLi都提供面向对象API,MySQLi同时还提供面向过程API,从传统的MySQL扩展接口移植到MySQLi接口非常简单,但PDO则可提供对多种数据库访问支持,所以,从业务种类角度来讲,PDO似乎应用更“广泛”一些,但MySQLi则更“专用”。

PDO支持十几种常见数据库,常见的MySQL、PostgreSQL、MS SQL Server、SQLite等等全部可使用PDO对应扩展支持,而接口部分及查询语句仅需要很少的改动,而PHP MySQLi扩展则只支持MySQL,要想支持别的数据改动会非常大。

当然,关于多数据库支持问题,其实似乎用处不大,“多数据库支持”就跟我们常说的“跨平台”一样,很多时候只是个概念炒作,仅仅为了少部分用户群体的需求就把架构做的冗大实质不值,任何程序皆为人设计,为人所用,最终目标都应该以易用、速度、效率和功耗作为追求目标。

四、命名参数

PDO绑定命名参数示例如下:

$params = array(':username' => 'test', ':email' => $mail, ':last_login' => time() - 3600);
    
$pdo->prepare('
   SELECT * FROM users
   WHERE username = :username
   AND email = :email
   AND last_login > :last_login');
    
$pdo->execute($params);

MySQLi不支持命名参数,绑定变量方法如下:

$query = $mysqli->prepare('
   SELECT * FROM users
   WHERE username = ?
   AND email = ?
   AND last_login > ?');
    
$query->bind_param('sss', 'test', $mail, time() - 3600);
$query->execute();

六、对象映射(Object mapping)

PDO和MySQLi均支持对象映射,对象映射提供对数据库记录集的方法封装(天缘自己赋的名称,对象映射的执行效果看起来有点类似eval的感觉),参考示例如下:

对象类定义:

class User {
   public $id;
   public $first_name;
   public $last_name;
    
   public function info()
   {
      return '#'.$this->id.': '.$this->first_name.' '.$this->last_name;
   }
}

调用类方法:

$query = "SELECT id, first_name, last_name FROM users";
    
// PDO
$result = $pdo->query($query);
$result->setFetchMode(PDO::FETCH_CLASS, 'User');
 
while ($user = $result->fetch()) {
   echo $user->info()."\n";
}
// MySQLI, procedural way
if ($result = mysqli_query($mysqli, $query)) {
   while ($user = mysqli_fetch_object($result, 'User')) {
      echo $user->info()."\n";
   }
}
// MySQLi, object oriented way
if ($result = $mysqli->query($query)) {
   while ($user = $result->fetch_object('User')) {
      echo $user->info()."\n";
   }
}

七、安全性

PDO和MySQLi均提供SQL防注入安全(jnjection security)方法,比如quote、escape等等,

// PDO, "manual" escaping
$username = PDO::quote($_GET['username']);

$pdo->query("SELECT * FROM users WHERE username = $username");

// mysqli, "manual" escaping
$username = mysqli_real_escape_string($_GET['username']);

$mysqli->query("SELECT * FROM users WHERE username = '$username'");

PDO::quote()不但转义字符串,还会引用它,而mysqli_real_escape_string()则只会转义字符串,所以,原作者推荐大家使用下面方法,而尽量减少使用而尽量不要使用PDO::quote()和mysqli_real_escape_string()。

// PDO, prepared statement
$pdo->prepare('SELECT * FROM users WHERE username = :username');
$pdo->execute(array(':username' => $_GET['username']));

// mysqli, prepared statements
$query = $mysqli->prepare('SELECT * FROM users WHERE username = ?');
$query->bind_param('s', $_GET['username']);
$query->execute();

关于PDO::quote()可参考:http://php.net/manual/zh/pdo.quote.php

八、总结

另外,作者还从性能等方面做了描述,不过天缘认为性能指标只是相对的,任何的数据库系统都应该从系统角度去衡量,都是整体权衡可用、效率、速度、扩展等方面需求下的结果。单从数据库引擎角度,PDO似乎略有小胜,支持多种类型数据库、名空间,PDO的运行效能则略低于MySQLi,这也很正常,MySQLi是定制的当然效率更高一些。 

原文地址(如不能访问,可能被拦截或干扰):

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

相关评论(0):  

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

订阅博客

最新文章

本站采用创作共用版权协议, 要求署名、非商业用途和保持一致. 转载也必须遵循“署名-非商业用途-保持一致”的创作共用协议. 返回顶部
Copyright@2005-2016 Metsky.com, All rights Reserved.