1.安裝 PDO
數據庫抽象層 PDO - PHP Data Object 擴展類庫為 PHP 訪問數據庫定義了一個輕量級的、一致性的接口,它提供了一個數據訪問抽象層,針對不同的數據庫服務器使用特定的 PDO 驅動程序訪問,如圖:
Windows 環境下 PHP 5.1 以上版本通過編輯 php.ini文件來安裝 PDO:去掉 extension=php_pdo.dll 前面的 ;
如果使用的數據庫是 MySQL ,在 php.ini 文件中加載 MySQL 的 PDO 驅動:
添加 extension=php_pdo_mysql.dll 或者去掉該句前面的 ;
查看可用的 PDO 驅動程序,可以編寫 php 文件進行查看:
<?php phpinfo();
如圖:
或者通過打印 pdo_drivers() 函數來查看:
<?phpprint_r(pdo_drivers());
頁面顯示:
Array ( [0] => mysql [1] => sqlite2 )
2.創建 PDO 對象
PDO 對象中的成員方法是統一各種數據庫的訪問接口,在使用 PDO 與數據庫交互之前,要創建 PDO 對象。在 PDO 的構造方法中,有 4 個參數:
1. 數據源名 DSN,用來定義一個確定的數據庫和必須用到的驅動程序
2. 連接數據庫的用戶名
3. 連接數據庫的密碼,是可選參數
4. 連接所需的所有額外選項,是可選參數
以 MySQL 為例,創建一個 PDO 對象:
//數據源名(DSN) $dsn = 'mysql:dbname=test;host=127.0.0.1';
$user = "root"; $pwd = ""; $opt = array(PDO::MYSQL_ATTR_INIT_COMMAND => "set names utf8"); $dbh = new PDO($dsn,$user,$pwd,$opt);
這里的第四個參數表示:向客戶端發送的 SQL 語句中使用 UTF8 字符集,同時服務器發送回客戶端的結果也是用 UTF8 字符集。
3. 調用構造方法
第一種方法是將參數嵌入到構造函數中,上面的例子用的就是這種方法:
<?php //數據源名(DSN) $dsn = 'mysql:dbname=test;host=127.0.0.1'; $user = "root"; $pwd = ""; $opt = array(PDO::MYSQL_ATTR_INIT_COMMAND => "set names utf8"); try{ $dbh = new PDO($dsn,$user,$pwd,$opt); }catch(PDOException $e){ echo "數據庫連接失敗: ".$e->getMessage(); exit; }
第二種方法是將 DSN 字符串存放在文件中,例如放在 d 盤相應目錄的 dsn.txt 中:
<?php $user = "root"; $pwd = ""; try{ $dbh = new PDO('uri:file:///d:\\practise\php\pdo\dsn.txt',$user,$pwd); }catch(PDOException $e){ echo "數據庫連接失敗: ".$e->getMessage(); }
這里使用了 uri ( 統一資源標識符 ) 來定位文件的位置。使用 PHP 的語句可以獲得當前 uri:
$uri = $_SERVER['REQUEST_URI']; echo $uri;
第三種方法是在 PHP 服務器的配置文件中維護 DSN 信息。
4.執行 SQL 語句
① 當執行 insert、update、delete 等沒有結果集的查詢時,使用 PDO 的 exec() 方法執行,執行成功后將返回受影響的行數。該方法不能用於 select 查詢:
1 <?php 2 3 //數據源名(DSN) 4 $dsn = 'mysql:dbname=test;host=127.0.0.1'; 5 $user = "root"; 6 $pwd = ""; 7 //第4個參數 8 $opt = array(PDO::MYSQL_ATTR_INIT_COMMAND => "set names utf8"); 9 10 try{ 11 12 $dbh = new PDO($dsn,$user,$pwd,$opt); 13 14 }catch(PDOException $e){ 15 16 echo "數據庫連接失敗: ".$e->getMessage(); 17 exit; 18 } 19 20 $query = "update archives set title = '白夜行' where title = '花的圓舞曲_3'"; 21 22 //使用exec()方法執行insert,update,delete等 23 $affected = $dbh->exec($query); 24 25 if($affected){ 26 27 echo '數據表archives中受影響的行數為:'.$affected; 28 29 }else{ 30 31 print_r($dbh->errorInfo()); 32 }
② 當執行返回結果集的 select 查詢時,或者所影響的行數無關緊要時,應當使用 PDO 對象中的 query() 方法,如果該方法成功執行所制定的查詢,則返回一個 PDOStatement 對象,並且可以使用 PDOStatement 對象的 rowCount() 方法獲取獲取的數據行數:
1 <?php 2 3 //數據源名(DSN) 4 $dsn = 'mysql:dbname=test;host=127.0.0.1'; 5 $user = "root"; 6 $pwd = ""; 7 //第4個參數 8 $opt = array(PDO::MYSQL_ATTR_INIT_COMMAND => "set names utf8"); 9 10 try{ 11 12 $dbh = new PDO($dsn,$user,$pwd,$opt); 13 $dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); 14 15 }catch(PDOException $e){ 16 17 echo "數據庫連接失敗: ".$e->getMessage(); 18 exit; 19 } 20 21 $query = "select * from archives where title='白夜行'"; 22 23 try{ 24 25 //執行select查詢,並返回PDOstatement對象 26 $pdostatement = $dbh->query($query); 27 echo "一共從表中獲取到".$pdostatement->rowCount()." 條記錄:<br>"; 28 foreach($pdostatement as $row){ 29 30 echo $row['aid']."<br>"; 31 } 32 }catch(PDOException $e){ 33 34 echo $e->getMessage(); 35 }
頁面顯示:
一共從表中獲取到11 條記錄:
540
541
544
547
550
553
556
559
562
565
568
5. 使用 PDO 過濾特殊字符,防止 SQL 注入,可以使用 PDO 的 quote() 方法:
$query = "select * from user where uname=".$dbh->quote($_POST['uname'])." and pwd=".$dbh->quote($_POST['pwd']);
參考資料:《細說PHP》第2版