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";
- }
- }
安全问题

最常见的当然是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,你可以考虑换了。
原文链接地址参考:
http://net.tutsplus.com/tutorials/php/pdo-vs-mysqli-which-should-you-use/
PDO vs. MySQLi 选择哪一个?(PDO vs. MySQLi: Which Should You Use?)-转载的更多相关文章
- PDO(PHP Data Object),Mysqli,以及对sql注入等问题的解决
这篇是上一篇 http://www.cnblogs.com/charlesblc/p/5987951.html 的续集. 看有的文章提到mysqli和PDO都支持多重查询,所以下面的url会造成表数据 ...
- MySQL原生API、MySQLi面向过程、MySQLi面向对象、PDO操作MySQL
[转载]http://www.cnblogs.com/52fhy/p/5352304.html 本文将举详细例子向大家展示PHP是如何使用MySQL原生API.MySQLi面向过程.MySQLi面向对 ...
- React 还是 Vue: 你应该选择哪一个Web前端框架?
学还是要学的,用的多了,也就有更多的认识了,开发中遇到选择的时候也就简单起来了. 本文作者也做了总结: 如果你喜欢用(或希望能够用)模板搭建应用,请使用Vue 如果你喜欢简单和“能用就行”的东西 ...
- 【游戏周边】Unity,UDK,Unreal Engine4或者CryENGINE——我应该选择哪一个游戏引擎
在digital-tutors看到的一篇文章,很多初学者都有这样的疑问,因此翻译到这里. 原文:http://blog.digitaltutors.com/unity-udk-cryengine-ga ...
- PDO连接mysql8.0报PDO::__construct(): Server sent charset (255) unknown to the client. Please, report to the developers错误
安装mysql8.0之后,尝试使用php连接mysql,总是报PDO::__construct(): Server sent charset (255) unknown to the client. ...
- PDO 学习与使用 ( 二 ) PDO 数据提取 和 预处理语句
以数据库 msg 为例,说明 PDO 的数据提取.预处理语句: mysql> show tables;+---------------+| Tables_in_msg |+----------- ...
- 跟着百度学PHP[14]-PDO的错误处理模式&PDO执行SQL
我们在使用PDO去执行sql语句的时候并不会报错.如下案例所示: <?php try { //$pdo = new pdo("mysql:host=主机;port=端口;dbname= ...
- C++ 函数重载,函数模板和函数模板重载,选择哪一个?
重载解析 在C++中,对于函数重载.函数模板和函数模板重载,C++需要有一个良好的策略,去选择调用哪一个函数定义(尤其是多个参数时),这个过程称为重载解析. (这个过程将会非常复杂,但愿不要遇到一定要 ...
- 开始VS 2012中LightSwitch系列的第3部分:我该选择哪一个屏幕模板
[原文发表地址] Beginning LightSwitch in VS 2012 Part 3: Screen Templates, Which One Do I Choose? [原文发表时间] ...
随机推荐
- php版本引起的const问题
刚刚遇到一个问题,类中定义了一个常量: const USER = ['aa', 'bb', 'cc']; 在类中的静态函数中调用以上常量不会出错.网站中所有的网页均能正常打开. 而当push到线上后, ...
- 使用mysql 命令行,增加 ,删除 字段 并 设置默认值 及 非空
使用mysql 命令行,增加 ,删除 字段 并 设置默认值 及 非空 添加 alter table table_name add field_name field_type; 添加,并设置默认值,及非 ...
- memcached 分布式
memcached定义 memcached 是一套分布式的高速缓存系统,被广泛应用于应用系统的缓存层来提升应用程序的访问速度:memcache缺乏认证以及安全管制,这表明应将memcached服务器放 ...
- 统一资源定位符URL类
package j2se.core.net.base; import java.io.BufferedReader;import java.io.IOException;import java.io. ...
- IIS发布WCF服务项目之本地
最近由于项目需求,要做一个上传文件附件的功能,由于是多用户访问,所以这就用到了WCF服务,程序编写完成就需要发布了, 下面记录下发布到IIS的过程: 1,安装IIS 第一步:检查Windows7中II ...
- MongoDB的真正性能-实战百万用户一-一亿的道具
使用情景 开始之前,我们先设定这样一个情景: 1.一百万注册用户的页游或者手游,这是不温不火的一个状态,刚好是数据量不上不下的一个情况.也刚好是传统MySql数据库性能开始吃紧的时候. 2.数据库就用 ...
- win10下搭建QTP测试环境
安装环境win 10 64位企业版 个人学习用1..net 3.5无法安装更新问题解决:打开windows update 服务2.win10 安装中提示为了对电脑进行保护,已经阻止此应用,请与管理员联 ...
- 使用 VisualCode + iTerm2 提交github的Pull Request
VisualCode集成github功能,是程序猿参与开源项目的利器.相比Sublime简单了很多(插件安装繁琐,比如你试试在Sublime2 安装gosublime,这里有坑; Sublime 3修 ...
- MCMC and Bayesian Data Analysis(PPT在文件模块)
How to generate a sample from $p(x)$? Let's first see how Matlab samples from a $p(x)$. In Matlab, t ...
- 《CODE》读后笔记——第14~20章
14.反馈与触发器 振荡器不需要人的干涉即可自主且不断地实现断开和闭合.所有计算机都靠某种振荡器来使其他部件同步工作. 当两个开关都断开时,电路有两个稳定状态,这样的一个电路称为触发器.触发器具有记忆 ...