PDO一是PHP數據對象(PHP Data Object)的縮寫。php
並不能使用PDO擴展自己執行任何數據庫操做,必須使用一個database-specific PDO driver(針對特定數據庫的PDO驅動)訪問數據庫服務器。
PDO並不提供數據庫抽象,它並不會重寫SQL或提供數據庫自己缺失的功能,若是你須要這種功能,你須要使用一個更加成熟的抽象層。
PDO須要PHP5核心OO特性的支持,因此它沒法運行於以前的PHP版本。
http://baike.baidu.com/view/1278977.htmhtml
PDO有很是多的操做倒是MySQL擴展庫所不具有的:mysql
1:PDO真正的以底層實現的統一接口數庫操做接口,無論後端使用的是何種數據庫,若是代碼封裝好了之後,應用層調用基本上差很少的,當後端數據庫更換了之後,應用層代碼基本不用修改.程序員
2:PDO支持更高級的DB特性操做,如:存儲過程的調度等,mysql原生庫是不支持的.web
3:PDO是PHP官方的PECL庫,兼容性穩定性必然要高於MySQL Extension,能夠直接使用 pecl upgrade pdo 命令升級.sql
4:PDO能夠防止SQL注入,確保數據庫更加安全
PDO 防止SQL注入的原理
http://www.myhack58.com/Article/60/61/2015/63168.htm數據庫
預處理語句
使用語句預處理將幫助你免於SQL注入攻擊。json
一條預處理語句是一條預編譯的 SQL 語句,它可使用屢次,每次只需將數據傳至服務器。其額外優點在於能夠對使用佔位符的數據進行安全處理,防止SQL注入攻擊。
http://www.php100.com/html/itnews/PHPxinwen/2013/0618/13555.htmlwindows
5.根據PHP官方計劃,PHP6正式到來之時,數據庫連接方式統一爲PDO。可是總有一小撮頑固分子,趁PHP官方還沒正式統一時,還用老式的MYSQL驅動連接數據庫。即便如今有部分程序改用Mysqli/pdo,只要沒用到預編譯,均和老式的Mysql驅動沒多大區別。在此,我就不點評國內的PHP生態環境了。
迴歸主題,爲何說PHP必需要用PDO?除了官方要求以外,我認爲做爲PHP程序員,只要你目前是作開發的話,那麼請選擇用PDO的程序/框架!PDO除了安全和萬金油式數據庫連接,還有一點是我目前以爲很是好用的!下面我就用我最近的切身體會來講。
業務環境:公司某老架構,數據庫設計的人員太菜了,設計過程徹底沒有按照數據庫範式進行。各類表中使用大量的序列化形式保存(補充:json同理)。
出現問題:銷售的客服反饋,網站某用戶在編輯地址時,Mysql報錯了。
問題猜測:不用說了。確定是引號,反斜槓引發序列化入庫不正常。
http://zhidao.baidu.com/question/1541430860923158627後端
6.安裝配置及測試
在windows下進行有關pdo測試的時候,php.ini中的extension_dir的值要填爲pdo*.dll的路徑,不然沒法運行pdo的相關程序。
; Directory in which the loadable extensions (modules) reside.
extension_dir = "E:\www\php5\ext"
1 <?php 2 $host = 'localhost'; 3 $user = 'root'; 4 $password = 'develop'; 5 $dbname = '99game'; 6 7 $dbh = new PDO("mysql:host=$host;dbname=$dbname", $user, $password); 8 9 //======================================================= 10 //例子 1. Execute a prepared statement with named placeholders 11 /* Execute a prepared statement by binding PHP variables */ 12 $user_id = 1; 13 $email = 'caihf_73940@qq.com'; 14 $sth = $dbh->prepare('SELECT user_id,email,token FROM 99game_user 15 WHERE user_id = :user_id AND email = :email'); 16 $sth->bindParam(':user_id', $user_id, PDO::PARAM_INT); 17 $sth->bindParam(':email', $email, PDO::PARAM_STR, 30); 18 $sth->execute(); 19 $result = $sth->fetch(PDO::FETCH_ASSOC); 20 print_r($result); 21 print("<br />\n"); 22 23 //例子 2. Execute a prepared statement with question mark placeholders 24 /* Execute a prepared statement by binding PHP variables */ 25 $user_id = 2; 26 $email = 'caihuafeng1@gmail.com'; 27 $sth = $dbh->prepare('SELECT user_id,email,token FROM 99game_user 28 WHERE user_id = ? AND email = ?'); 29 $sth->bindParam(1, $user_id, PDO::PARAM_INT); 30 $sth->bindParam(2, $email, PDO::PARAM_STR, 30); 31 $sth->execute(); 32 $result = $sth->fetch(PDO::FETCH_ASSOC); 33 print_r($result); 34 print("<br />\n"); 35 36 print "<hr />\n"; 37 //======================================================= 38 39 //======================================================= 40 $sth = $dbh->prepare("SELECT user_id,email,token FROM 99game_user limit 10"); 41 $sth->execute(); 42 43 /* 運用 PDOStatement::fetch 風格 */ 44 print("PDO::FETCH_ASSOC: "); 45 print("Return next row as an array indexed by column name<br />\n"); 46 $result = $sth->fetch(PDO::FETCH_ASSOC); 47 print_r($result); 48 print("<br />\n"); 49 print("\n"); 50 51 print("PDO::FETCH_BOTH: "); 52 print("Return next row as an array indexed by both column name and number<br />\n"); 53 $result = $sth->fetch(PDO::FETCH_BOTH); 54 print_r($result); 55 print("<br />\n"); 56 print("\n"); 57 58 print("PDO::FETCH_LAZY: "); 59 print("Return next row as an anonymous object with column names as properties<br />\n"); 60 $result = $sth->fetch(PDO::FETCH_LAZY); 61 print_r($result); 62 print("<br />\n"); 63 print("\n"); 64 65 print("PDO::FETCH_OBJ: "); 66 print("Return next row as an anonymous object with column names as properties<br />\n"); 67 $result = $sth->fetch(PDO::FETCH_OBJ); 68 print_r($result); 69 print 'user_id:' . $result->user_id; 70 print("<br />\n"); 71 print("\n"); 72 73 print "<hr />\n"; 74 //======================================================= 75 76 //======================================================= 77 function readDataForwards($dbh) { 78 $sql = 'SELECT user_id,email,token FROM 99game_user limit 10'; 79 try { 80 $stmt = $dbh->prepare($sql, array(PDO::ATTR_CURSOR, PDO::CURSOR_SCROLL)); 81 $stmt->execute(); 82 while ($row = $stmt->fetch(PDO::FETCH_NUM, PDO::FETCH_ORI_NEXT)) { 83 $data = $row[0] . "\t" . $row[1] . "\t" . $row[2] . "<br />\n"; 84 print $data; 85 } 86 $stmt = null; 87 } 88 catch (PDOException $e) { 89 print $e->getMessage(); 90 } 91 } 92 93 function readDataBackwards($dbh) { 94 $sql = 'SELECT user_id,email,token FROM 99game_user limit 10'; 95 try { 96 $stmt = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL)); 97 $stmt->execute(); 98 $row = $stmt->fetch(PDO::FETCH_NUM, PDO::FETCH_ORI_LAST); 99 do { 100 $data = $row[0] . "\t" . $row[1] . "\t" . $row[2] . "<br />\n"; 101 print $data; 102 } while ($row = $stmt->fetch(PDO::FETCH_NUM, PDO::FETCH_ORI_PRIOR)); 103 $stmt = null; 104 } 105 catch (PDOException $e) { 106 print $e->getMessage(); 107 } 108 } 109 110 print "Reading forwards:<br />\n"; 111 readDataForwards($dbh); 112 113 print "<hr />\n"; 114 115 print "Reading backwards:<br />\n"; 116 //下面的數據沒有按照想像中的倒排輸出,暫時不知道什麼緣由,php.net官方手冊中的例子也是這麼寫的 117 readDataBackwards($dbh); 118 //======================================================= 119 ?>
以上測試程序輸出以下:
Array
(
[user_id] => 1
[email] => caihf_73940@qq.com
[token] => 123token456_73940
)
Array
(
[user_id] => 2
[email] => caihuafeng1@gmail.com
[token] => 33fadfasdfadsf
)
PDO::FETCH_ASSOC: Return next row as an array indexed by column name
Array
(
[user_id] => 1
[email] => caihf_73940@qq.com
[token] => 123token456_73940
)
PDO::FETCH_BOTH: Return next row as an array indexed by both column name and number
Array
(
[user_id] => 2
[0] => 2
[email] => caihuafeng1@gmail.com
[1] => caihuafeng1@gmail.com
[token] => 33fadfasdfadsf
[2] => 33fadfasdfadsf
)
PDO::FETCH_LAZY: Return next row as an anonymous object with column names as properties
PDORow Object
(
[queryString] => SELECT user_id,email,token FROM 99game_user limit 10
[user_id] => 3
[email] => caihf_61039@qq.com
[token] => 123token456_61039
)
PDO::FETCH_OBJ: Return next row as an anonymous object with column names as properties
stdClass Object
(
[user_id] => 6
[email] => aa1@aa.com
[token] => cU8ady73epcmf54o7W0q1F0f8R3b2y4d
)
user_id:6
Reading forwards:
1 caihf_73940@qq.com 123token456_73940
2 caihuafeng1@gmail.com 33fadfasdfadsf
3 caihf_61039@qq.com 123token456_61039
6 aa1@aa.com cU8ady73epcmf54o7W0q1F0f8R3b2y4d
7 caihuafengqq@gmail.com 1wcl3j1a92bgc6eb8Y9rcQbjen5I8f7F
8 caihuafeng@163.com 90debU1x3ddWdSdc239hdF2t1AeScf3w
9 caihuafeng@gmail.com 1V1D8xao3O9m1mdq5706716kbx5u6n58
10 test@test.com b28de59ddc824ed8a8556514dd83c348
11 test2@test2.com 965e5873e6dbba4af57b96dfe0b027e7
12 caihf@qq.com_69054 123token456_69054
Reading backwards:
1 caihf_73940@qq.com 123token456_73940
2 caihuafeng1@gmail.com 33fadfasdfadsf
3 caihf_61039@qq.com 123token456_61039
6 aa1@aa.com cU8ady73epcmf54o7W0q1F0f8R3b2y4d
7 caihuafengqq@gmail.com 1wcl3j1a92bgc6eb8Y9rcQbjen5I8f7F
8 caihuafeng@163.com 90debU1x3ddWdSdc239hdF2t1AeScf3w
9 caihuafeng@gmail.com 1V1D8xao3O9m1mdq5706716kbx5u6n58
10 test@test.com b28de59ddc824ed8a8556514dd83c348
11 test2@test2.com 965e5873e6dbba4af57b96dfe0b027e7
12 caihf@qq.com_69054 123token456_69054
延伸閱讀:
http://www.baidu.com/s?wd=php%20pdo%20%E4%BC%98%E7%82%B9
http://www.sogou.com/web?query=php%20pdo%20優勢
https://www.so.com/s?q=php%20pdo%20%E4%BC%98%E7%82%B9
http://www.open-open.com/lib/view/open1419950418859.html
PHP5中PDO的簡單使用
http://blog.csdn.net/leo115/article/details/7538983
php pdo操做數據庫
http://www.cnblogs.com/yujon/p/5476176.html
爲何 PHP 應該使用 PDO 方式訪問數據庫
http://www.php100.com/html/itnews/PHPxinwen/2013/0618/13555.html
PDO預處理語句PDOStatement對象使用總結
http://www.jb51.net/article/57609.htm