当前位置: 首页 > news >正文

PDO和MySQLi区别和数度;到底用哪个?

当用PHP访问数据库时,除了PHP自带的数据库驱动,我们一般还有两种比较好的选择:PDO和MySQLi。在实际开发过程中要决定选择哪一种首先要对二者有一个比较全面的了解。本文就针对他们的不同点进行分析,并对多数据库类型支持、稳定性、性能等等方面进行对比。

 

 
PDOMySQLi
Database support12 different driversMySQL only
APIOOPOOP + procedural
ConnectionEasyEasy
Named parametersYesNo
Object mappingYesYes
Prepared statements 
(client side)
YesNo
PerformanceFastFast
Stored proceduresYesYes

 

 

一、连接

复制代码
// 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,这种形式对于新手来说更容易理解。如果你对原生的php mysql 驱动熟悉,你会发现很轻松得就能使用MySQLi的接口来替换原来的数据访问。用PDO的好处是,PDO支持多种数据库,而MySQLi只支持MySQL,一但你掌握了就你可以随心所欲的使用连接多种数据库。

三、数据库的支持

PDO比MySQLi最大的优点就是PDO支持很多种数据库,而MySQLi只支持MySQLi。要看PDO支持哪些数据库用下面的代码:

var_dump(PDO::getAvailableDrivers());

支持多数据库有什么好处呢?当你的程序以后想从mysql换成sql server或者oracle时,PDO的优势就能体现出来了,因为换数据库对于程序接口是透明的,php代码改动很小,如果你是用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();
复制代码

我们从上面对比就可以看出PDO是通过命名参数进行值的绑定,而MySQLi的参数绑定是通过点位符“?”并严格按这个问号的顺序来绑定值。这样虽然代码显得没有PDO那种通过名字对应那么长,但是有一个不好的地方是可读性和可维护性都降低了,参数个数比较少的时候还不觉得,当参数上了10多个或者更多的情况就比较痛苦了,你必须要按问号的顺序来一个一个对应来赋值,万一其中一个位错了,后面的都跟着错了。

不幸的是MySQLi不支持PDO那样的命名参数绑定。

五、对象映射(Object Mapping)

基于数据库的开发一般都是从数据库中读取数据然后把这些数据用一个对象来承载。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;
    }
}
复制代码

如果没有对象映射,我们要读取数据之后,一个一个字段的赋值,这是很繁琐的。

下面请看二者使用对象的代码:

复制代码
$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['username'] = "'; DELETE FROM users; /*"

当用户输入的username参数的值为上面的值("'; DELETE FROM users; /*"),如果你没有对这个值做任何处理,用户就成功将delete语句注入,那么user表的记录就会被全部删除。

6.1、手动转义

复制代码
// 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和MySQLi的API自带的函数对获取到的参数的值进行了转义。

6.2、prepared statement参数绑定

下面推荐更加高效安全的prepared statement参数绑定的方式:

复制代码
// 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能够支持其它非MySQL的数据库,而MySQLi专门针对MySQL设计的,所以MySQLi相对于PDO性能稍微好一些。但是PDO和MySQLi都还是没有PHP原生的MySQL扩展快。但是这样性能比较其实意义不太大,因为它们都是相当快了,如果你的程序性能要求不是特别苛刻话,三者都可以满足你。至于你要选择哪一种就要你根据的实践情况进行权衡。

八、总结

PDO支持12种数据库驱动和命名参数绑定是其最大优点,通过上面的对比,我相信你也知道了你在自己的项目中会使用哪一种连接数据库了?

转载于:https://www.cnblogs.com/wanglijun/p/9458890.html

相关文章:

  • android 换行符(\n) 在TextView中显示不正常的问题
  • App上线-Missing App Store Icon
  • Windows 环境Oracle客户端下载安装
  • datetime模块的简单用法
  • JVM 内存解析,以及自己的一些见解
  • 对CRC32的小结加上bugku一道题目:好多压缩包
  • Excel-DNA自定义函数的参数智能提示功能:ExcelDna.IntelliSense1.1.0.rar
  • D05——C语言基础学PYTHON
  • 常见HTTP状态码
  • 蓝牙学习(4) -- L2CAP
  • c#窗体项目:工艺注意事项
  • Linux 常用命令——文件处理命令
  • python 爬虫 5i5j房屋信息 获取并存储到数据库
  • HDU - 2255 奔小康赚大钱 KM算法 模板题
  • LDAP概念和原理
  • 「译」Node.js Streams 基础
  • Apache的80端口被占用以及访问时报错403
  • co.js - 让异步代码同步化
  • Java 实战开发之spring、logback配置及chrome开发神器(六)
  • js写一个简单的选项卡
  • LeetCode541. Reverse String II -- 按步长反转字符串
  • MQ框架的比较
  • React-flux杂记
  • Service Worker
  • vue和cordova项目整合打包,并实现vue调用android的相机的demo
  • vue中实现单选
  • 阿里云购买磁盘后挂载
  • 二维平面内的碰撞检测【一】
  • 高程读书笔记 第六章 面向对象程序设计
  • 码农张的Bug人生 - 见面之礼
  • 写给高年级小学生看的《Bash 指南》
  • 优秀架构师必须掌握的架构思维
  • 带你开发类似Pokemon Go的AR游戏
  • 翻译 | The Principles of OOD 面向对象设计原则
  • 如何用纯 CSS 创作一个货车 loader
  • 专访Pony.ai 楼天城:自动驾驶已经走过了“从0到1”,“规模”是行业的分水岭| 自动驾驶这十年 ...
  • ​比特币大跌的 2 个原因
  • #设计模式#4.6 Flyweight(享元) 对象结构型模式
  • (二)【Jmeter】专栏实战项目靶场drupal部署
  • (简单) HDU 2612 Find a way,BFS。
  • (原創) 如何讓IE7按第二次Ctrl + Tab時,回到原來的索引標籤? (Web) (IE) (OS) (Windows)...
  • (最完美)小米手机6X的Usb调试模式在哪里打开的流程
  • .net 4.0发布后不能正常显示图片问题
  • .net core webapi 部署iis_一键部署VS插件:让.NET开发者更幸福
  • .NET Core中的去虚
  • .Net 访问电子邮箱-LumiSoft.Net,好用
  • .NET设计模式(7):创建型模式专题总结(Creational Pattern)
  • .sh文件怎么运行_创建优化的Go镜像文件以及踩过的坑
  • @Query中countQuery的介绍
  • [120_移动开发Android]008_android开发之Pull操作xml文件
  • [20171106]配置客户端连接注意.txt
  • [Angular] 笔记 20:NgContent
  • [C#]使用DlibDotNet人脸检测人脸68特征点识别人脸5特征点识别人脸对齐人脸比对FaceMesh
  • [excel与dict] python 读取excel内容并放入字典、将字典内容写入 excel文件
  • [Git].gitignore失效的原因