2013年8月3日 星期六

PDO - 取得資料的方式

引用
<?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

沒有留言:

張貼留言