<?php ini_set("display_errors", "On"); error_reporting(E_ALL ^E_NOTICE ^E_DEPRECATED); define('DB_DATABASE','dbname'); define('DB_USERNAME','username'); define('DB_PASSWORD','password'); define('DB_HOSTNAME','localhost'); define('DB_TYPE','mysql'); $dsn = DB_TYPE.':host='.DB_HOSTNAME.';dbname='.DB_DATABASE; $dbh = new PDO($dsn, DB_USERNAME, DB_PASSWORD, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")); $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $sql = "SELECT NOW();"; $row = $dbh->query($sql)->fetch(PDO::FETCH_ASSOC); echo "<pre>", print_r($row, 1), "</pre>";
第 1 招:使用 pdo 的 query 方法直接取得資料
最基本的用法:$sql = "UPDATE table_name SET aaa='aaa', bbb='bbb' WHERE id='id'"; $dbh->query($sql);
查詢單筆資料
$sql = "SELECT * FROM table_name WHERE id='id' LIMIT 1"; $row = $dbh->query($sql)->fetch(PDO::FETCH_ASSOC);
查詢多筆資料
$sql = "SELECT * FROM table_name WHERE id='id' LIMIT 10"; foreach ( $dbh->query($sql) as $row){ echo "<pre>".print_r($row,1)."</pre>"; };
可以包在 try-catch 裡面,這樣如果有有問題會顯示錯誤訊息:
<?php $sql = "SELECT * FROM table_name LIMIT 10"; try{ foreach ( $dbh->query($sql) as $row){ echo "<pre>".print_r($row,1)."</pre>"; }; } catch (PDOException $e) { die($e->getMessage()); } ?>
第 2 招:將 query 方法傳回的結果另外存成物件
$sql = "SELECT * FROM table_name LIMIT 10"; $result = $dbh->query($sql); while($row = $result->fetch(PDO::FETCH_ASSOC)){ //do something }這個範例是用欄位名稱做陣列元素的鍵值。若要使用欄位順序的號碼,可改用 FETCH_NUM 。請參考這裡。
第 3 招:使用命名參數
$DataArray = array(array('cust_id'=>'ID001', 'cust_name'=>'Name1'), array('cust_id'=>'ID002', 'cust_name'=>'Name2'), array('cust_id'=>'ID003', 'cust_name'=>'Name3') ); echo "<pre>".print_r($Rowsets, 1)."</pre>"; $sql = "INSERT INTO test_table (cust_id, cust_name) VALUES(:cust_id, :cust_name)"; $result = $dbh->prepare($sql); foreach($DataArray as $arr) { $result->bindParam(':cust_id', $arr['cust_id']); $result->bindParam(':cust_name', $arr['cust_name']); $result->execute(); }如果要插入很多筆資料,可以使用這種方式。先把 INSERT 的基本語句透過 prepare 方法準備好,然後再使用迴圈一筆一筆插入。聽說效率會比舊的 mysql_query 函數更好。
這種方式也可以用於查詢:
$cust_id = '20130803001'; $sql = "SELECT * FROM $tb WHERE cust_id = :cust_id"; echo "<pre>".print_r($sql, 1)."</pre>"; $result = $dbh->prepare($sql); $result->bindParam(':cust_id', $cust_id, PDO::PARAM_STR, 12);//第3、4個參數指定型態、長度 $result->execute(); while($row = $result->fetch(PDO::FETCH_ASSOC)) { echo "<pre>".print_r($row, 1)."</pre>"; }
第 4 招:使用問號參數
$math = 85; $english = 80; $sql = "SELECT * FROM class WHERE math > ? AND english > ?"; $result = $dbh->prepare($sql); $result->bindParam(1, $math, PDO::PARAM_INT);//第3個參數指定欄位型態 $result->bindParam(2, $english, PDO::PARAM_INT); $result->execute(); while($row = $result->fetch(PDO::FETCH_ASSOC)) { echo "<pre>".print_r($row, 1)."</pre>"; } $count = $result->rowCount();
第 5 招:將參數寫到execute()方法裡面
$sql = "SELECT `name`, `location` FROM `users` WHERE `location` = ? , `name` = ?"; $result = $dbh->prepare($sql); $result->execute(array($location, $name)); $rowOBJ = $result->fetch(PDO::FETCH_OBJ); echo $rowOBJ->name . $rowOBJ->location;
第 6 招:將結果集一次全抓回來
$sql = "SELECT * FROM test_table WHERE cust_id=:cust_id AND cust_type=:cust_type"; $result = $dbh->prepare($sql); $result->bindParam(':cust_id', $_GET['cust_id']); $result->bindParam(':cust_type', $_GET['cust_type']); $result->execute(); $Rowset = $result->fetchAll(PDO::FETCH_ASSOC); echo "<pre>".print_r($Rowset,1)."</pre>";
第 7 招:將結果集分組
假設有這樣一組數據apple yellow
apple green
apple red
pear yellow
pear red
orange yellow
$sql = "SELECT name, colour FROM fruit"; $result = $dbh->prepare($sql); $result->execute(); $Rowset = $result->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_GROUP); echo "<pre>".print_r($Rowset,1)."</pre>";
會得到這樣的結果
Array
(
[apple] => Array
(
[0] => green
[1] => red
[2] => yellow
)
[pear] => Array
(
[0] => red
[1] => yellow
)
[orange] => Array
(
[0] => yellow
)
)
如果沒有使用這個方法,就要這樣處理。
while($row = $result->...){ $key = $row['name']; $Rowset[$key][] = $row['colour']; }
索引類型
PDO::FETCH_ASSOC
PDO::FETCH_NUM
PDO::FETCH_BOTH
PDO::FETCH_OBJ
PDO::FETCH_BOUND 這個要搭配 bindColumn 使用
延伸閱讀
PDO 基本用法
PHP & MYSQL PDO 使用方法
淺談 PHP-MySQL, PHP-MySQLi, PDO 的差異
PHP Data Objects
PDOStatement::nextRowset (微軟,有搭配 fetchAll 使用)
PDOStatement::fetchAll
Codeigniter with PDO
沒有留言:
張貼留言