具體參考《PHP核心技術(shù)與最佳實(shí)踐》的5.1章 《什么是PDO》
1. PDO的介紹PHP針對(duì)每種數(shù)據(jù)庫(kù)都有一個(gè)獨(dú)立的模塊、一組獨(dú)立的函數(shù)。這樣的結(jié)構(gòu)和設(shè)計(jì)讓PHP兼容多種數(shù)據(jù)庫(kù)變得困難。一旦要將一個(gè)應(yīng)用移到另外一種數(shù)據(jù)庫(kù)環(huán)境中,或者是需要添加新的數(shù)據(jù)庫(kù)支持,就不得不重新編寫和數(shù)據(jù)庫(kù)相關(guān)的操作。通常編寫多個(gè)類,用適配器模式來實(shí)現(xiàn)。在這個(gè)歷史背景下PDO出現(xiàn)了。PDO(PHP Data Objects)提供了一個(gè)通用接口訪問多種數(shù)據(jù)庫(kù),即抽象的數(shù)據(jù)模型支持連接多種數(shù)據(jù)庫(kù)。有了PDO使代碼變得更簡(jiǎn)潔、更安全。
在PHP中,連接MySQL數(shù)據(jù)庫(kù)的通常有3種方式:
MySQL系列函數(shù):最常用,是過程式風(fēng)格的一組應(yīng)用(不建議,在PHP7.0已廢除)
MySQLi系列函數(shù):是MySQL函數(shù)的增強(qiáng)改進(jìn)版,提供了過程化和面向?qū)ο髢煞N風(fēng)格的API,增加了預(yù)編譯和參數(shù)綁定等新的特性
PDO:從語法上講,PDO更接近MySQLi
具體的可以參考:【連接數(shù)據(jù)庫(kù)】PHP7的連接數(shù)據(jù)庫(kù)的三種方法【原創(chuàng)】
相比MySQLi,PDO的優(yōu)勢(shì)在于支持多種數(shù)據(jù)庫(kù),而MySQLi只能支持MySQL,所以一般更推薦使用PDO來對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作。
PDO提供了一個(gè)數(shù)據(jù)訪問抽象層,這就意味著不管使用哪種數(shù)據(jù)庫(kù),都可以用同樣一組API對(duì)數(shù)據(jù)進(jìn)行操作,保證了可抽象性和訪問接口的一致性。
開啟PDO很容易,一般來說安裝好PHP默認(rèn)都會(huì)開啟PDO,如果沒有則去php.ini中找到以下語句,把前面的分號(hào)去掉即可
;extension=php_pdo.dll2. PDO的使用
使用PDO的第一步是配置數(shù)據(jù)源,之后的用法和MySQL擴(kuò)展操作數(shù)據(jù)庫(kù)的方法沒有什么區(qū)別了,
PDO的操作主要有PDO::query()、PDO::exec()、PDO::prepare()
PDO::query():主要是用于有記錄結(jié)果返回的操作,特別是SELECT操作
PDO::exec():主要是針對(duì)沒有結(jié)果集合返回的操作,比如INSERT、UPDATE、DELETE等操作,它返回的結(jié)果是當(dāng)前操作影響的列數(shù)
PDO::prepare():主要是預(yù)處理操作,需要通過$rs->execute()來執(zhí)行預(yù)處理里面的SQL語句,這個(gè)方法可以綁定參數(shù),功能比較強(qiáng)大
以下是PDO的示例:
setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $db->exec("SET NAMES "UTF8""); // 插入到日志中 $sql = "INSERT INTO users(name, email, password, created_at) values ("pdo_test", "8888@qq.com", "bbb", now())"; $db->exec($sql); // 使用預(yù)處理語句 $insert = $db->prepare("INSERT INTO users(name, email, password, created_at) values (?, ?, ?, now())"); $insert->execute(array("pdo_test1", "8448657@qq.com", "aaa")); // 異常 $insert->execute(array("pdo_test2", "8448657@qq.com", "aaa", 9, 10)); $sql = "select name, email, password, created_at from users"; $query = $db->prepare($sql); $query->execute(); var_dump($query->fetchAll(PDO::FETCH_ASSOC)); } catch (PDOException $e) { echo $e->getMessage(); }
注意:使用PDO從MySQL數(shù)據(jù)庫(kù)查詢出來的數(shù)據(jù)都是string類型的,在某些特殊應(yīng)用下,可能需要轉(zhuǎn)換格式
3. PDO的參數(shù)綁定和預(yù)編譯PDO最大的特點(diǎn)就是引入?yún)?shù)綁定和預(yù)編譯。
下面是從數(shù)據(jù)庫(kù)中查詢某條記錄:
query("SELECT name FROM users WHERE id = " . $_GET["id"]);
這是一段糟糕的代碼。插入一個(gè)原始的請(qǐng)求參數(shù)到 SQL 請(qǐng)求中。這將讓被黑客輕松地利用[SQL 注入]方式進(jìn)行攻擊。想一下如果黑客將一個(gè)構(gòu)造的 id 參數(shù)通過像 http://domain.com/?id=1%3BDEL... 這樣的 URL 傳入。這將會(huì)使 $_GET["id"] 變量的值被設(shè)為 1;DELETE FROM users 然后被執(zhí)行從而刪除所有的 user 記錄!因此,你應(yīng)該使用 PDO 限制參數(shù)來過濾 ID 輸入。
上面的代碼可優(yōu)化為:
prepare("SELECT name FROM users WHERE id = :id"); $id = filter_input(INPUT_GET, "id", FILTER_SANITIZE_NUMBER_INT); $stmt->bindParam(":id", $id, PDO::PARAM_INT); $stmt->execute();
在MySQL應(yīng)用中,為了防止注入攻擊,通常在PHP中使用intval、addslashes等函數(shù)對(duì)傳入的參數(shù)進(jìn)行轉(zhuǎn)義,轉(zhuǎn)變?yōu)镾QL中合法的參數(shù)類型,這種方法較復(fù)雜,而使用PDO的bindParam方法會(huì)變得很快捷,只需要在函數(shù)中指定第三個(gè)參數(shù),即可對(duì)傳入的參數(shù)進(jìn)行轉(zhuǎn)換,轉(zhuǎn)換為需要的類型拼接到原生的SQL語句中
比如:
prepare("SELECT name, colour, calories FROM fruit WHERE calories > :calories AND colour = :colour"); // 綁定變量,將變量轉(zhuǎn)化為int類型 $sth->bindParam(":calories", $calories, PDO::PARAM_INT); // 綁定變量,將變量轉(zhuǎn)化為string類型 $sth->bindParam(":colour", $colour, PDO::PARAM_STR, 12); // 執(zhí)行 $sth->execute(); var_dump($sth->fetchAll(PDO::FETCH_ASSOC)); // 執(zhí)行預(yù)處理語句(第二種綁定變量的方式) $sth = $db->prepare("SELECT name, colour, calories FROM fruit WHERE calories > ? AND colour = ?"); // 綁定變量,將變量轉(zhuǎn)化為int類型 $sth->bindParam(1, $calories, PDO::PARAM_INT); // 綁定變量,將變量轉(zhuǎn)化為string類型 $sth->bindParam(2, $colour, PDO::PARAM_STR, 12); // 執(zhí)行 $sth->execute(); var_dump($sth->fetchAll(PDO::FETCH_ASSOC));
預(yù)編譯負(fù)責(zé)兩件事,轉(zhuǎn)義和軟解析提速。程序要支持預(yù)編譯,除了要數(shù)據(jù)庫(kù)支持外,還需要驅(qū)動(dòng)支持(PDO和MySQLi均支持)
4. PDO事務(wù)處理一個(gè)事務(wù)中所有的工作在提交時(shí),即使是分階段執(zhí)行,也要保證安全的應(yīng)用于數(shù)據(jù)庫(kù),不被其他的連接干擾,事務(wù)工作可以在請(qǐng)求發(fā)生錯(cuò)誤時(shí)自動(dòng)取消。
事務(wù)的主要特性:原子性、一致性、獨(dú)立性、持久性(Atomicity,Consistency,Isolation,Durability,ACID)。典型運(yùn)用就是通過把批量的改變保存,然后立即執(zhí)行,這樣就能提高效率,一旦事務(wù)不成功,將會(huì)回滾到初始狀態(tài),保證數(shù)據(jù)的一致性。
SQL通常工作在自動(dòng)提交模式下,這意味著執(zhí)行的每個(gè)查詢都有自己隱含的事務(wù)處理,無論是數(shù)據(jù)庫(kù)支持事務(wù)還是因數(shù)據(jù)庫(kù)不支持而不存在事務(wù),DML語句執(zhí)行的結(jié)果都將立即生效而不可更改。比如在MySQL中執(zhí)行一條update語句,其功能將會(huì)立即生效并且是永久性不可更改性的。而在Oracle數(shù)據(jù)庫(kù)中,默認(rèn)是事務(wù)模式,要delete一條數(shù)據(jù),數(shù)據(jù)并不會(huì)被永久性刪除,只有執(zhí)行了commit命令后才會(huì)生效。
PDO中使用beginTransaction()方法來創(chuàng)建事務(wù)。在一個(gè)事務(wù)中,使用commit()或者是rollback()方法來結(jié)束事務(wù),具體應(yīng)用哪種方法這取決于事務(wù)中代碼運(yùn)行是否成功。腳本結(jié)束或者一個(gè)連接要關(guān)閉時(shí),如果還有一個(gè)未處理完的事務(wù),PDO自動(dòng)將其回滾。這對(duì)于腳本意外終止情況來說是一個(gè)安全方案,如果沒有明確提交事務(wù),它將假設(shè)發(fā)生一些錯(cuò)誤,為數(shù)據(jù)的安全執(zhí)行回滾。
自動(dòng)回滾僅發(fā)生于通過beginTransaction()建立的事務(wù)。如果用手動(dòng)方式執(zhí)行一個(gè)開始事務(wù)的查詢,PDO無法知道他的情況故無法回滾。
代碼如下:
beginTransaction(); for($i = 0; $i < 1000000; $i++) { $conn->exec("insert into `users` values(null, "username")"); } // 提交事務(wù) $conn->commit(); } catch(PDOException $ex) { // 執(zhí)行回滾 $conn->rollBack(); }
注意:因?yàn)槭褂昧耸聞?wù),要么成功要么失敗,如果發(fā)現(xiàn)第一條執(zhí)行了,但是第二條沒有執(zhí)行或者是失敗了,則應(yīng)該檢查一下表類型是否為MyISAM,MyISAM引擎是不支持事務(wù)的,需要改用InnoDB或者其他的支持事務(wù)的引擎。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/17664.html
摘要:是什么首先思考為什么選擇是一個(gè)數(shù)據(jù)訪問抽象層抽象是雙重的一個(gè)是眾所周知但不太重要的另一個(gè)是模糊的但是是最重要的眾所周知為不同的數(shù)據(jù)庫(kù)提供了統(tǒng)一的接口雖然這個(gè)功能本身很龐大但是對(duì)于固定程序來說不是過于重要的事情基本所有的程序都是使用統(tǒng)一的后端 PDO是什么 首先思考, 為什么選擇PDO PDO 是一個(gè)數(shù)據(jù)訪問抽象層(Database Access Abstraction Layer). ...
具體參考《PHP核心技術(shù)與最佳實(shí)踐》的5.1章 《什么是PDO》 1. PDO的介紹 PHP針對(duì)每種數(shù)據(jù)庫(kù)都有一個(gè)獨(dú)立的模塊、一組獨(dú)立的函數(shù)。這樣的結(jié)構(gòu)和設(shè)計(jì)讓PHP兼容多種數(shù)據(jù)庫(kù)變得困難。一旦要將一個(gè)應(yīng)用移到另外一種數(shù)據(jù)庫(kù)環(huán)境中,或者是需要添加新的數(shù)據(jù)庫(kù)支持,就不得不重新編寫和數(shù)據(jù)庫(kù)相關(guān)的操作。通常編寫多個(gè)類,用適配器模式來實(shí)現(xiàn)。在這個(gè)歷史背景下PDO出現(xiàn)了。PDO(PHP Data Objec...
摘要:操作數(shù)據(jù)庫(kù)的種形式使用擴(kuò)展類庫(kù)推薦使用擴(kuò)展類庫(kù)這是類庫(kù)的升級(jí)版,但已經(jīng)不推薦使用擴(kuò)展包含哪三個(gè)類與區(qū)別可以支持多種數(shù)據(jù)庫(kù),而且操作方法一致只支持?jǐn)?shù)據(jù)庫(kù)如何使用連接數(shù)據(jù)庫(kù)什么是如何關(guān)閉連接通過來連接數(shù)據(jù)庫(kù),其中必須傳入數(shù)據(jù)源名稱數(shù)據(jù)源名稱是 PHP操作數(shù)據(jù)庫(kù)的2種形式 使用 PDO 擴(kuò)展類庫(kù)(推薦) 使用 Mysqli 擴(kuò)展類庫(kù)(這是Mysql類庫(kù)的升級(jí)版,但已經(jīng)不推薦使用) PDO...
閱讀 2571·2021-11-24 09:38
閱讀 2601·2019-08-30 15:54
閱讀 915·2019-08-30 15:52
閱讀 1909·2019-08-30 15:44
閱讀 2713·2019-08-30 13:48
閱讀 768·2019-08-29 16:21
閱讀 996·2019-08-29 14:03
閱讀 2212·2019-08-28 18:15