自PHP5.5開(kāi)始,傳統(tǒng)的mysql擴(kuò)展已經(jīng)廢棄,只能使用PHP提供的html' target='_blank'>MySQLi擴(kuò)展或PDO擴(kuò)展,那么它們之間的區(qū)別有哪些呢?本文匯總此兩種連接的各自特點(diǎn),主要從數(shù)據(jù)庫(kù)支持、穩(wěn)定性及性能等方面做個(gè)簡(jiǎn)單比較,僅供設(shè)計(jì)參考。
申明:本文翻譯來(lái)源于文本鏈接地址,天緣在該文基礎(chǔ)上稍作補(bǔ)充修整,如有不明之處,請(qǐng)直接訪問(wèn)文末原文鏈接。
一、PDO和MySQLi區(qū)別下表列出PDO和MySQLi的幾個(gè)典型方面區(qū)別:

更多方面比較也可參考另一篇文章:
http://www.php.net/manual/zh/mysqlinfo.api.choosing.php
二、連接方式PDO和mysqli創(chuàng)建連接方式如下:
// 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和數(shù)據(jù)庫(kù)PDO和MySQLi都提供面向?qū)ο?/u>API,MySQLi同時(shí)還提供面向過(guò)程API,從傳統(tǒng)的MySQL擴(kuò)展接口移植到MySQLi接口非常簡(jiǎn)單,但PDO則可提供對(duì)多種數(shù)據(jù)庫(kù)訪問(wèn)支持,所以,從業(yè)務(wù)種類角度來(lái)講,PDO似乎應(yīng)用更“廣泛”一些,但MySQLi則更“專用”。
PDO支持十幾種常見(jiàn)數(shù)據(jù)庫(kù),常見(jiàn)的MySQL、PostgreSQL、MS SQL Server、SQLite等等全部可使用PDO對(duì)應(yīng)擴(kuò)展支持,而接口部分及查詢語(yǔ)句僅需要很少的改動(dòng),而PHP MySQLi擴(kuò)展則只支持MySQL,要想支持別的數(shù)據(jù)改動(dòng)會(huì)非常大。
當(dāng)然,關(guān)于多數(shù)據(jù)庫(kù)支持問(wèn)題,其實(shí)似乎用處不大,“多數(shù)據(jù)庫(kù)支持”就跟我們常說(shuō)的“跨平臺(tái)”一樣,很多時(shí)候只是個(gè)概念炒作,僅僅為了少部分用戶群體的需求就把架構(gòu)做的冗大實(shí)質(zhì)不值,任何程序皆為人設(shè)計(jì),為人所用,最終目標(biāo)都應(yīng)該以易用、速度、效率和功耗作為追求目標(biāo)。
四、命名參數(shù)PDO綁定命名參數(shù)示例如下:
$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不支持命名參數(shù),綁定變量方法如下:
$query = $mysqli->prepare(' SELECT * FROM users WHERE username = ? AND email = ? AND last_login > ?'); $query->bind_param('sss', 'test', $mail, time() - 3600);$query->execute();六、對(duì)象映射(Object mapping)PDO和MySQLi均支持對(duì)象映射,對(duì)象映射提供對(duì)數(shù)據(jù)庫(kù)記錄集的方法封裝(天緣自己賦的名稱,對(duì)象映射的執(zhí)行效果看起來(lái)有點(diǎn)類似eval的感覺(jué)),參考示例如下:
對(duì)象類定義:
class User { public $id; public $first_name; public $last_name; public function info() { return '#'.$this->id.': '.$this->first_name.' '.$this->last_name; }}
調(diào)用類方法:
$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 wayif ($result = mysqli_query($mysqli, $query)) { while ($user = mysqli_fetch_object($result, 'User')) { echo $user->info()."/n"; }}// MySQLi, object oriented wayif ($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()不但轉(zhuǎn)義字符串,還會(huì)引用它,而mysqli_real_escape_string()則只會(huì)轉(zhuǎn)義字符串,所以,原作者推薦大家使用下面方法,而盡量減少使用而盡量不要使用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();關(guān)于PDO::quote()可參考:http://php.net/manual/zh/pdo.quote.php
八、總結(jié)另外,作者還從性能等方面做了描述,不過(guò)天緣認(rèn)為性能指標(biāo)只是相對(duì)的,任何的數(shù)據(jù)庫(kù)系統(tǒng)都應(yīng)該從系統(tǒng)角度去衡量,都是整體權(quán)衡可用、效率、速度、擴(kuò)展等方面需求下的結(jié)果。單從數(shù)據(jù)庫(kù)引擎角度,PDO似乎略有小勝,支持多種類型數(shù)據(jù)庫(kù)、名空間,PDO的運(yùn)行效能則略低于MySQLi,這也很正常,MySQLi是定制的當(dāng)然效率更高一些。
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。
新聞熱點(diǎn)
疑難解答
圖片精選