mysql sql 应该选择哪一个_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

链接

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

// 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的API,那么迁移到MySQLi也非常容易。另一方面,一旦你选择了PDO,你就可以用在任何你想要使用的数据库上。

数据库支持

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

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

var_dump(PDO::getAvailableDrivers());

这意味着什么?

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

名称式参数

这是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();

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

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

对象映射

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

class User {

public $id;

public $first_name;

public $last_name;

public function info()

{

return '#'.$this->id.': '.$this->first_name.' '.$this->last_name;

}

}

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

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

$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";

}

}

安全问题

0_13299681481UPN.gif

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

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

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

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

对$_GET数据处理

// 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只是转义了字符串,需要自己手动加单引号。

下面是prepared statements的方式查询

// 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();

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

性能

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

总结

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

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

原文链接地址参考:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值