PDO多種方式取得查詢結果

PDO最大的特點之一是它的靈活性,本節將介紹如何取得查詢結果,包括:

數組(數值或關聯數組);

字符串(單列的結果集);

對象;

回調函數。

1.快取一行

FetchColumn是爲應用程序取得一個僅包含單列的數據,代碼如下:

$u = $db->query(“SELECT id FROM users WHERE login=‘login’ AND password=‘password’”);
fetch(PDO::FETCH_COLUMN)
if ($u->fetchColumn()) { //返回一個字符串
//登錄成功
} else {
//驗證失敗
}

2.取得一個標準對象

還可以將取得的一行作爲一個標準類stdClass的對象實例,其中列名=屬性名。

$res = $db->query(“SELECT * FROM foo”);
while ($obj = $res->fetch(PDO::FETCH_OBJ)) {
// $obj == instance of stdClass
}

3.存取爲一個類

PDO允許將結果保存爲一個類,例子如下:

$res = $db->query(“SELECT * FROM foo”);
$res->setFetchMode(
PDO::FETCH_CLASS,
“className”,
array(‘optional’=‘Constructor Params’)
);
while ($obj = $res->fetch()) {
// $obj == instance of className
}

4.從一個類取得常量

PDO允許查詢的結果可以被用來生成一個目的類。

$res = $db->query(“SELECT * FROM foo”);
$res->setFetchMode(
PDO::FETCH_CLASS |
PDO::FETCH_CLASSTYPE
);
while ($obj = $res->fetch()) {
// $obj == instance of class who’s name is
// found in the value of the 1st column
}

5.存取爲一個對象

PDO還允許獲取數據到一個已經存在的對象。

$u = new userObject;
$res = $db->query(“SELECT * FROM users”);
$res->setFetchMode(PDO::FETCH_INTO$u);
while ($res->fetch()) {
// 取得的記錄集將放在$u這個對象變量中,在此顯示
}

6.存取爲關聯數據

PDO實現了迭代器(Iteator)接口,允許一個方法實現迭代的功能。

$res = $db->query(
“SELECT * FROM users”,
PDO::FETCH_ASSOC
);
foreach ($res as $row) {
// $row是一個關聯數組,可以直接顯示,如$row['id']
}

7.fetchAll()方法

PDO也提供了和ADODB類似的fetchAll()方法,它允許從一個結果集中取得數據,然後放於關聯數組中。

$db->setAttribute(PDO::ATTR_CASE, PDO::CASE_UPPER);
$qry = “SELECT * FROM users”;
$res = $db->query($qry)->fetchAll(PDO::FETCH_ASSOC);
?>
或者獲取到索引數組裏:
$res = $db->query("SELECT * FROM foo");
$result_arr = $res->fetchAll();
print_r($result_arr);

數字索引數組比較浪費資源,請儘量使用關聯數組,這樣可以在內存中使用相當密集的大型結果集。
相關說明如下:

setAttribute()方法用於設置部分屬性,主要屬性有:PDO::ATTR_CASE、PDO::ATTR_ERRMODE等,這裏需要設置的是PDO::ATTR_CASE,就是使用關聯索引獲取數據集時,關聯索引是大寫還是小寫,有如下幾個選擇:

PDO::CASE_LOWER——強制列名是小寫;

PDO::CASE_NATURAL——列名按照原始的方式;

PDO::CASE_UPPER——強制列名爲大寫。

我們使用setFetchMode方法來設置獲取結果集的返回值的數據類型,類型有:

PDO::FETCH_ASSOC——關聯數組形式;

PDO::FETCH_NUM——數字索引數組形式;

PDO::FETCH_BOTH——兩種數組形式都有,這是默認的;

PDO::FETCH_OBJ——按照對象的形式,類似於以前的 mysql_fetch_object()。

當然,一般情況下,我們使用PDO::FETCH_ASSOC取得關聯數組。具體使用哪種類型,應按照自己的實際應用選擇。

8.fetchColumn()方法

如果想獲取指定記錄裏的一個字段結果,則可以使用PDOStatement::fetchColumn()。

$rs = $db->query("SELECT COUNT(*) FROM foo");
$col = $rs->fetchColumn();
echo $col;

一般使用fetchColumn()方法進行count統計,對某些只需要單字段的記錄可以很好地操作。

9.回調函數

PDO還規定在每一個fetch模式下,經過處理後的結果中使用一個回調函數。

function draw_message($subject$email) { … }
$res = $db->query(“SELECT * FROM msg”);
$res->fetchAll(PDO::FETCH_FUNC,“draw_message”);

10.直接查詢的問題

直接使用Query查詢行每次都會直接提交給數據庫,如果查詢較多,每次頻頻查詢將導致效率降低。
另外,在安全問題上,沒有過濾一些特殊字符容易產生SQL注入。

11.過濾字符

下面我們來看看如何使用PDO進行過濾引起SQL注入的方法,即過濾特殊字符。我們在PDO中使用quote()方法,使用例子如下:

$query = “SELECT * FROM users WHERE
login=“.$db->quote($_POST[‘login’]).”
AND
passwd=“.$db->quote($_POST[‘pass’]);

12.事務處理

PDO驅動程序支持所有的事務數據庫,並且PDO提供更簡便的方法,如下:

$db->beginTransaction();
if ($db->exec($qry) === FALSE) {
$db->rollback();
}
$db->commit();

13.執行一個批處理事務

在下面的示例中,假設我們爲一個新僱員創建一組條目,這個僱員有一個ID號,即23。除了輸入這個僱員的基本數據外,還需要記錄僱員的薪水。分別完成兩個更新很簡單,但通過將這兩個更新包括在beginTransaction()和commit()調用中,就可以保證在更改完成之前,其他人無法看到更改。如果發生了錯誤,catch塊可以回滾事務開始以來發生的所有更改,並打印出一條錯誤消息。代碼內容如下:

try {
    $dbh = new PDO('odbc:SAMPLE''db2inst1''ibmdb2'array(PDO_ATTR_PERSISTENT => true));
    echo "Connected\n";
    $dbh->setAttribute(PDO_ATTR_ERRMODE, PDO_ERRMODE_EXCEPTION);
    $dbh->beginTransaction();
    $dbh->exec("insert into staff (id, first, last)
    values (23, 'Joe', 'Bloggs')");
    $dbh->exec("insert into salarychange (id, amount, changedate) 
    values (23, 50000, NOW())");
    $dbh->commit();
} catch (Exception $e) {
    $dbh->rollBack();
    echo "Failed: " . $e->getMessage();
}

並不是一定要在事務中做出更新,也可以通過複雜的查詢來提取數據,還可以使用信息構建更多的更新和查詢。當事務在活動時,可以保證其他人在工作進行當中無法做出更改。事實上,這不是100%的正確,但如果您之前沒有聽說過事務的話,這樣介紹也未嘗不可。
下面是一個擴展PDO&PDO語句的類,內容如下:


class Database extends PDO{
    function __construct(){
        parent::__construct('mysql:dbname=test;host=localhost''root''');
        $this->setAttribute(PDO::ATTR_STATEMENT_CLASS,
        array('DBStatement'array($this)));
    }
}

class DBStatement extends PDOStatement{
    public $dbh;
    protected function __construct($dbh){
    $this->dbh = $dbh;
    $this->setFetchMode(PDO::FETCH_OBJ);
}
public function foundRows(){
    $rows = $this->dbh->prepare('SELECT found_rows()
    AS rows'array(PDO::MYSQL_ATTR_ USE_BUFFERED_QUERY =
    > TRUE));
    $rows->execute();
    $rowsCount = $rows->fetch(PDO::FETCH_OBJ)->rows;
    $rows->closeCursor();
    return $rowsCount;
    }
}

14.存儲過程

在MySQL一章,我們已經瞭解了存儲過程的創建,下面我們來看使用PDO調用的例子:

$stmt = $dbh->prepare("CALL sp_set_string(?)");
$stmt->bindParam(1, $str);
$str = ‘hospinfo’; //綁定參數
$stmt->execute();

與先前講過的綁定例子差不多,只是這裏使用了“?”數據綁定方法,sp_set_string是存儲過程名稱。
帶有輸出參數的存儲過程:

$stmt = $dbh->prepare("CALL sp_get_string(?)");
$stmt->bindParam(1, $ret,PDO:ARAM_STR, 4000);
if ($stmt->execute()) {
    echo "返回值 $ret\n";
}

下面是綁定列輸出的腳本例子:

$stmt = $dbh->prepare("SELECT extension, name from CREDITS");
if ($stmt->execute()) {
    $stmt->bindColumn('extension', $extension);
    $stmt->bindColumn('name', $name);
    while ($stmt->fetch(PDO::FETCH_BOUND)) {
        echo "Extension: $extension\n";
        echo "Author: $name\n";
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章