前端學PHP之PDO預處理語句

前面的話

  原本要把預處理語句和前面的基礎操做寫成一篇的。可是,因爲博客園的限制,多是由於長度超出,保存時老是報錯,因而再開一篇。另外一方面,相較於前面的exec()和query()語句來講,預處理語句更加經常使用php

 

定義

  在生成網頁時,許多PHP腳本一般都會執行除參數以外,其餘部分徹底相同的查詢語句,針對這種重複執行一個查詢,每次迭代使用不一樣的參數狀況,PDO提供了一種名爲預處理語句(prepared statement)的機制。它能夠將整個SQL命令向數據庫服務器發送一次,之後只有參數發生變化,數據庫服務器只需對命令的結構作一次分析就夠了,即編譯一次,能夠屢次執行。會在服務器上緩存查詢的語句和執行過程,而只在服務器和客戶端之間傳輸有變化的列值,以此來消除這些額外的開銷。這不只大大減小了須要傳輸的數據量,還提升了命令的處理效率。能夠有效防止SQL注入,在執行單個查詢時快於直接使用query()或exec()的方法,速度快且安全,推薦使用mysql

  PDO對預處理語句的支持須要使用PDOStatement類對象,但該類的對象並非經過NEW關鍵字實例化出來的,而是經過執行PDO對象的prepare()方法,在數據庫服務器中準備好一個預處理的SQL語句後直接返回的。若是經過以前執行PDO對象的query()方法返回的PDOStatement類對象,只表明的是一個結果集對象。而若是經過執行PDO對象中的prepare()方法產生的PDOStatement類對象,則爲一個查詢對象,能定義和執行參數化的SQL命令sql

 

準備語句

  重複執行一個SQL查詢,經過每次迭代使用不一樣的參數,這種狀況使用預處理語句運行效率最高。使用預處理語句,首先須要在數據庫服務器中先準備好「一個SQL語句」,但並不須要立刻執行。PDO支持使用「佔位符」語法,將變量綁定到這個預處理的SQL語句中。另外,PDO幾乎爲所支持的全部數據庫提供了命令佔位符模擬,甚至能夠爲生來就不支持該概念的數據庫模擬預處理語句和綁定參數。這是PHP向前邁進的積極一步,由於這樣可使開發人員可以用PHP編寫「企業級」的數據庫應用程序,而沒必要特別關注數據庫平臺的能力數據庫

  對於一個準備好的SQL語句,若是在每次執行時都要改變一些列值,這種狀況必須使用「佔位符」而不是具體的列值,或者只要有須要使用變量做爲值的地方,就先使用佔位符替代,準備好一個沒有傳值的SQL語句,在數據庫服務器的緩存區等待處理,而後再去單獨賦給佔位符具體的值,再經過這個準備好的預處理語句執行。在PDO中有兩種使用佔位符的語法:「命令參數」和「問號參數」,使用哪種語法看我的的喜愛數組

  使用命名參數做爲佔位符的INSERT查詢以下所示:緩存

$dbh->prepare("INSERT INTO contactInto(name,address,phone)VALUES (:name,:address,:phone)");

  須要自定義一個字符串做爲「命名參數」,每一個命名參數須要冒號(:)開始,參數的命名必定要有意義,最好和對應的字段名稱相同安全

  使用問號(?)參數做爲佔位符的INSERT查詢以下所示:服務器

$dbh->prepare("INSERT INTO contactInfo(name,address,phone) VALUES (?,?,?)");

  問號參數必定要和字段的位置順序對應,不論是使用哪種參數做爲佔位符構成的查詢,或是語句中沒有用到佔位符,都須要使用PDO對象中的prepare()方法,去準備這個將要用於迭代執行的查詢,並返回PDOStatement類對象函數

 

綁定參數

  當SQL語句經過PDO對象中的prepare()方法,在數據庫服務器端準備好以後,若是使用了佔位符,就須要在每次執行時替換輸入的參數。能夠經過PDOStatement對象中的bindParam()方法,把參數變量綁定到準備好的佔位符上(位置或名字要對應)。方法bindParame()的原型以下所示:fetch

bool PDOStatement::bindParam ( mixed $parameter , mixed &$variable [, int $data_type = PDO::PARAM_STR [, int $length [, mixed $driver_options ]]] )

  綁定一個PHP變量到用做預處理的SQL語句中的對應命名佔位符或問號佔位符。不一樣於 PDOStatement::bindValue(),此變量做爲引用被綁定,並只在PDOStatement::execute()被調用的時候才取其值

  parameter表示參數標識符(必須項)。對於使用命名佔位符的預處理語句,應是相似:name形式的參數名。對於使用問號佔位符的預處理語句,應是以1開始索引的參數位置

  variable(必須項)表示綁定到 SQL 語句參數的 PHP 變量名

  data_type(可選項)表示使用PDO::PARAM_*常量明確地指定參數的類型。要從一個存儲過程當中返回一個INOUT參數,須要爲data_type參數使用按位或操做符去設置PDO::PARAM_INPUT_OUTPUT位,能夠爲如下值

PDO:PARAM_BOOL:表示boolean數據類型
PDO:PARAM_NULL:表示NULL數據類型
PDO:PARAM_INT:表示INT數據類型
PDO:PARAM_STR:表示字符串數據類型
PDO:PARAM_LOB:表示大對象數據類型

  length(可選項)表示數據類型的長度。爲代表參數是一個存儲過程的OUT參數,必須明確地設置此長度

  使用bindParam()方法分別綁定上對應的參數。查詢中使用名字參數的綁定以下所示

$query = "INSERT INTO contactInfo (name,address,phone) VALUES (:name,:address,:phone)";
$stmt = $dbh->prepare($query);
$stmt->bindParam(":name",$name);
$stmt->bindParam(":address",$address);
$stmt->bindParam(":phone",$phone);
$name = '愛新覺羅';
$address = '東城';
$phone = '88888';

  查詢中使用問號?參數的綁定以下所示

$query = "INSERT INTO contactInfo (name,address,phone) VALUES (?,?,?)";
$stmt = $dbh->prepare($query);
$stmt->bindParam("1",$name);
$stmt->bindParam("2",$address);
$stmt->bindParam("3",$phone);
$name = '司馬';
$address = '西城';
$phone = '666';

 

執行查詢

  當準備好查詢並綁定了相應的參數後,就能夠經過調用PDOStatement類對象中的execute()方法,反覆執行在數據庫緩存區準備好的語句了。在下面的示例中,向前面提供的contactInfo表中,使用預處理方式連續執行同一個INSERT語句,經過改變不一樣的參數添加兩條記錄

<?php
try {
    //建立對象
    $dbh = new PDO("mysql:host=localhost;dbname=testdb", "root", "***");
}catch(PDOException $e) {
    echo "數據庫鏈接失敗:".$e->getMessage();
    exit;
}
$query = "INSERT INTO contactInfo (name,address,phone) VALUES (?,?,?)";
$stmt = $dbh->prepare($query);
$stmt->bindParam("1",$name);
$stmt->bindParam("2",$address);
$stmt->bindParam("3",$phone);
$name = '司馬';
$address = '西城';
$phone = '666';
$stmt->execute();

$name = '曹操';
$address = '平谷';
$phone = '1';
$stmt->execute();
?>
<?php
try {
    //建立對象
    $dbh = new PDO("mysql:host=localhost;dbname=testdb", "root", "***");
}catch(PDOException $e) {
    echo "數據庫鏈接失敗:".$e->getMessage();
    exit;
}
$query = "INSERT INTO contactInfo (name,address,phone) VALUES (:name,:address,:phone)";
$stmt = $dbh->prepare($query);
$stmt->bindParam(":name",$name);
$stmt->bindParam(":address",$address);
$stmt->bindParam(":phone",$phone);
$name = '愛新覺羅';
$address = '東城';
$phone = '88888';
$stmt->execute();
?>

  若是隻是要傳遞輸入參數,而且有許多這樣的參數要傳遞,那麼經過在execute()方法中提供一個可選參數,該參數是由準備查詢中的命名參數佔位符組成的數組,這是第二種爲預處理查詢在執行中替換輸入參數的方式。此語法能夠活動對bindParam()的調用

<?php
try {
    //建立對象
    $dbh = new PDO("mysql:host=localhost;dbname=testdb", "root", "***");
}catch(PDOException $e) {
    echo "數據庫鏈接失敗:".$e->getMessage();
    exit;
}
$query = "INSERT INTO contactInfo (name,address,phone) VALUES (?,?,?)";
$stmt = $dbh->prepare($query);
$stmt->execute(array("張飛",'延慶','3'));

$query = "INSERT INTO contactInfo (name,address,phone) VALUES (:name,:address,:phone)";
$stmt = $dbh->prepare($query);
$stmt->execute(array(":name"=>"關羽",":address"=>"密雲",":phone"=>"2"));
?>

  若是執行的是INSERT語句,而且數據表有自動增加的ID字段,可使用PDO對象中的lastInsertId()方法獲取最後插入數據表中的記錄ID。若是須要查看其餘DML語句是否執行成功,能夠經過PDOStatement類對象中的rowCount()方法獲取影響記錄的行數

<?php
try {
    //建立對象
    $dbh = new PDO("mysql:host=localhost;dbname=testdb", "root", "***");
}catch(PDOException $e) {
    echo "數據庫鏈接失敗:".$e->getMessage();
    exit;
}
$query = "INSERT INTO contactInfo (name,address,phone) VALUES (?,?,?)";
$stmt = $dbh->prepare($query);
$stmt->execute(array("孫權",'通州','123456'));
echo $dbh->lastInsertId();

$query = "UPDATE contactInfo SET name=? WHERE uid=?";
$stmt = $dbh->prepare($query);
$stmt->execute(array("天使","6"));
echo $stmt->rowCount();//1

$query = "DELETE FROM contactInfo  WHERE name= ?";
$stmt = $dbh->prepare($query);
$stmt->execute(["孫權"]);
echo $stmt->rowCount();//11
?>

 

獲取數據

  PDO的數據獲取方法與其餘數據庫擴展都很是相似,只要成功執行SELECT查詢,都會有結果集對象生成。不論是使用PDO對象中的query()方法,仍是使用prepare()和execute()等方法結合的預處理語句,執行SELECT查詢都會獲得相同的結果集對象PDOStatement,都須要經過PDOStatement類對象中的方法將數據遍歷出來

fetch()

  PDOStatement類中的fetch()方法能夠將結果集中當前行的記錄以某種方式返回,並將結果集指針移到下一行,當到達結果集末尾時返回FALSE,該方法的原型以下:

mixed PDOStatement::fetch ([ int $fetch_style [, int $cursor_orientation = PDO::FETCH_ORI_NEXT [, int $cursor_offset = 0 ]]] )

  第一個參數fetch_style(可選項),用於控制下一行如何返回給調用者。此值必須是 PDO::FETCH_* 系列常量中的一個,缺省爲 PDO::ATTR_DEFAULT_FETCH_MODE 的值(默認爲 PDO::FETCH_BOTH)

PDO::FETCH_ASSOC:返回一個索引爲結果集列名的數組
PDO::FETCH_BOTH(默認):返回一個索引爲結果集列名和以0開始的列號的數組
PDO::FETCH_BOUND:返回 TRUE ,並分配結果集中的列值給 PDOStatement::bindColumn() 方法綁定的 PHP 變量。
PDO::FETCH_CLASS:返回一個請求類的新實例,映射結果集中的列名到類中對應的屬性名。若是 fetch_style 包含 PDO::FETCH_CLASSTYPE(例如:PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE),則類名由第一列的值決定
PDO::FETCH_INTO:更新一個被請求類已存在的實例,映射結果集中的列到類中命名的屬性
PDO::FETCH_LAZY:結合使用PDO::FETCH_BOTH和PDO::FETCH_OBJ,建立供用來訪問的對象變量名
PDO::FETCH_NUM:返回一個索引爲以0開始的結果集列號的數組
PDO::FETCH_OBJ:返回一個屬性名對應結果集列名的匿名對象

  第二個參數cursor_orientation(可選項)表示對於一個PDOStatement對象表示的可滾動遊標,該值決定了哪一行將被返回給調用者。此值必須是 PDO::FETCH_ORI_* 系列常量中的一個,默認爲 PDO::FETCH_ORI_NEXT。要想讓 PDOStatement 對象使用可滾動遊標,必須在用 PDO::prepare() 預處理SQL語句時,設置 PDO::ATTR_CURSOR 屬性爲 PDO::CURSOR_SCROLL

  第三個參數offset(可選項)表示對於一個cursor_orientation參數設置爲PDO::FETCH_ORI_ABS的PDOStatement對象表明的可滾動遊標,此值指定結果集中想要獲取行的絕對行號

  對於一個 cursor_orientation 參數設置爲 PDO::FETCH_ORI_REL 的PDOStatement 對象表明的可滾動遊標,此值指定想要獲取行相對於調用 PDOStatement::fetch() 前遊標的位置

<?php
try {
    //建立對象
    $dbh = new PDO("mysql:host=localhost;dbname=testdb", "root", "***");
}catch(PDOException $e) {
    echo "數據庫鏈接失敗:".$e->getMessage();
    exit;
}
$query = "SELECT uid,name,address,phone,email FROM contactInfo";
$stmt = $dbh->prepare($query);
$stmt->execute();
//Array ( [uid] => 1 [0] => 1 [name] => 張三 [1] => 張三 [address] => 朝陽 [2] => 朝陽 [phone] => 123 [3] => 123 [email] => zs@aaa.com [4] => zs@aaa.com ) 
print_r($stmt->fetch());
echo "<br>";
//Array ( [uid] => 2 [0] => 2 [name] => 李四 [1] => 李四 [address] => 朝陽 [2] => 朝陽 [phone] => 123456789 [3] => 123456789 [email] => ls@aaa.com [4] => ls@aaa.com ) 
print_r($stmt->fetch());
echo "<br>";
?>
<?php
try {
    //建立對象
    $dbh = new PDO("mysql:host=localhost;dbname=testdb", "root", "***");
}catch(PDOException $e) {
    echo "數據庫鏈接失敗:".$e->getMessage();
    exit;
}
$query = "SELECT uid,name,address,phone,email FROM contactInfo";
$stmt = $dbh->prepare($query);
$stmt->execute();
/*
Array ( [0] => 1 [1] => 張三 [2] => 朝陽 [3] => 123 [4] => zs@aaa.com ) 
Array ( [0] => 2 [1] => 李四 [2] => 朝陽 [3] => 123456789 [4] => ls@aaa.com ) 
Array ( [0] => 3 [1] => 王五 [2] => 海淀 [3] => 15011113456 [4] => ww@aaa.com ) 
Array ( [0] => 4 [1] => 趙四 [2] => 海淀 [3] => 123456789 [4] => zx@aaa.com ) 
Array ( [0] => 5 [1] => 諸葛 [2] => [3] => 120120120 [4] => zg@aaa.com ) 
Array ( [0] => 6 [1] => 天使 [2] => [3] => 222 [4] => zg2@aaa.com ) 
Array ( [0] => 7 [1] => 司馬 [2] => 西城 [3] => 666 [4] => ) 
Array ( [0] => 8 [1] => 曹操 [2] => 平谷 [3] => 1 [4] => ) 
Array ( [0] => 9 [1] => 愛新覺羅 [2] => 東城 [3] => 88888 [4] => ) 
Array ( [0] => 10 [1] => 張飛 [2] => 延慶 [3] => 3 [4] => ) 
Array ( [0] => 11 [1] => 關羽 [2] => 密雲 [3] => 2 [4] => ) 
 */
while($row = $stmt->fetch(PDO::FETCH_NUM)){
    print_r($row);
    echo "<br>";    
}
?>

  下面以表格的形式輸出結果集

<?php
try {
    //建立對象
    $dbh = new PDO("mysql:host=localhost;dbname=testdb", "root", "***");
}catch(PDOException $e) {
    echo "數據庫鏈接失敗:".$e->getMessage();
    exit;
}
$query = "SELECT uid,name,address,phone,email FROM contactInfo";
$stmt = $dbh->prepare($query);
$stmt->execute();
echo '<table border="1" >';
echo "<th>編號</th>";
echo "<th>姓名</th>";
echo "<th>地址</th>";
echo "<th>電話</th>";
echo "<th>郵箱</th>";
while(list($uid, $name, $address, $phone, $email) = $stmt -> fetch(PDO::FETCH_NUM)) {
    echo '<tr>';
    echo '<td>'.$uid.'</td>';
    echo '<td>'.$name.'</td>';
    echo '<td>'.$address.'</td>';
    echo '<td>'.$phone.'</td>';
    echo '<td>'.$email.'</td>';
    echo '</tr>';
}
echo '</table>';
?>

fetchAll()

  fetchAll()方法與上一個方法fetch()相似,可是該方法只須要調用一次就能夠獲取結果集中的全部行,並賦給返回的二維數組。該方法的原型以下:

fetchAll([int fetch_style [,int column_index]])

  第一個參數fetch_style是可選項,以何種方式引用所獲取的列取決於該參數。默認值爲PDO::FETCH_BOTH,全部可用的值能夠參考在fetch()方法中介紹的第一個參數的列表,還能夠指定PDO::FETCH_COLUMN值,從結果集中返回一個包含單列的全部值

  第二個參數column_index是可選項,須要提供一個整數索引,當在fetchAll()方法的第一個參數中指定PDO::FETCH_COLUMN值時,從結果集中返回經過該參數提供的索引所指定列的全部值

/*
Array ( [0] => Array ( [uid] => 1 [0] => 1 [name] => 張三 [1] => 張三 [address] => 朝陽 [2] => 朝陽 [phone] => 123 [3] => 123 [email] => zs@aaa.com [4] => zs@aaa.com ) [1] => Array ( [uid] => 2 [0] => 2 [name] => 李四 [1] => 李四 [address] => 朝陽 [2] => 朝陽 [phone] => 123456789 [3] => 123456789 [email] => ls@aaa.com [4] => ls@aaa.com ) [2] => Array ( [uid] => 3 [0] => 3 [name] => 王五 [1] => 王五 [address] => 海淀 [2] => 海淀 [phone] => 15011113456 [3] => 15011113456 [email] => ww@aaa.com [4] => ww@aaa.com ) [3] => Array ( [uid] => 4 [0] => 4 [name] => 趙四 [1] => 趙四 [address] => 海淀 [2] => 海淀 [phone] => 123456789 [3] => 123456789 [email] => zx@aaa.com [4] => zx@aaa.com ) [4] => Array ( [uid] => 5 [0] => 5 [name] => 諸葛 [1] => 諸葛 [address] => [2] => [phone] => 120120120 [3] => 120120120 [email] => zg@aaa.com [4] => zg@aaa.com ) [5] => Array ( [uid] => 6 [0] => 6 [name] => 天使 [1] => 天使 [address] => [2] => [phone] => 222 [3] => 222 [email] => zg2@aaa.com [4] => zg2@aaa.com ) [6] => Array ( [uid] => 7 [0] => 7 [name] => 司馬 [1] => 司馬 [address] => 西城 [2] => 西城 [phone] => 666 [3] => 666 [email] => [4] => ) [7] => Array ( [uid] => 8 [0] => 8 [name] => 曹操 [1] => 曹操 [address] => 平谷 [2] => 平谷 [phone] => 1 [3] => 1 [email] => [4] => ) [8] => Array ( [uid] => 9 [0] => 9 [name] => 愛新覺羅 [1] => 愛新覺羅 [address] => 東城 [2] => 東城 [phone] => 88888 [3] => 88888 [email] => [4] => ) [9] => Array ( [uid] => 10 [0] => 10 [name] => 張飛 [1] => 張飛 [address] => 延慶 [2] => 延慶 [phone] => 3 [3] => 3 [email] => [4] => ) [10] => Array ( [uid] => 11 [0] => 11 [name] => 關羽 [1] => 關羽 [address] => 密雲 [2] => 密雲 [phone] => 2 [3] => 2 [email] => [4] => ) )
 */
print_r($stmt->fetchAll());

  下面以表格的形式輸出結果集

<?php
try {
    //建立對象
    $dbh = new PDO("mysql:host=localhost;dbname=testdb", "root", "***");
}catch(PDOException $e) {
    echo "數據庫鏈接失敗:".$e->getMessage();
    exit;
}
$query = "SELECT uid,name,address,phone,email FROM contactInfo";
$stmt = $dbh->prepare($query);
$stmt->execute();

echo '<table border="1" >';
echo "<th>編號</th>";
echo "<th>姓名</th>";
echo "<th>地址</th>";
echo "<th>電話</th>";
echo "<th>郵箱</th>";
$allRows = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach($allRows as $row){
    echo '<tr>';
    echo '<td>'.$row['uid'].'</td>';
    echo '<td>'.$row['name'].'</td>';
    echo '<td>'.$row['address'].'</td>';
    echo '<td>'.$row['phone'].'</td>';
    echo '<td>'.$row['email'].'</td>';
    echo '</tr>';
}
echo '</table>';
?>

  下面使用fetchAll()方法輸出全部的姓名數組

$query = "SELECT uid,name,address,phone,email FROM contactInfo";
$stmt = $dbh->prepare($query);
$stmt->execute();
$row=$stmt->fetchAll(PDO::FETCH_COLUMN,1);
echo '全部聯繫人的姓名:';
//全部聯繫人的姓名:Array ( [0] => 張三 [1] => 李四 [2] => 王五 [3] => 趙四 [4] => 諸葛 [5] => 天使 [6] => 司馬 [7] => 曹操 [8] => 愛新覺羅 [9] => 張飛 [10] => 關羽 )
print_r($row);

setFetchMode()

  PDOStatement對象中的fetch()和fetchAll()兩個方法,獲取結果數據的引用方式默認是同樣的,既按列名索引又按列在行中的數值偏移(從0開始)索引的值數組,由於它們的默認模式都被設置爲PDO::FETCH_BOTH值,若是計劃使用其餘模式來改變這個默認設置,能夠在fetch()或fetchAll()方法中提供須要的模式參數。但若是屢次使用這兩個方法,在每次調用時都須要設置新的模式來改變默認的模式。這時就可使用PDOStatement類對象中的setFetchMode()方法,在腳本頁面的頂部設置一次模式,之後全部fetch()和fetchAll()方法的調用都將生成相應引用的結果集,減小了屢次在調用fetch()方法時的參數錄入

$query = "SELECT uid,name,address,phone,email FROM contactInfo";
$stmt = $dbh->prepare($query);
$stmt->execute();
$stmt->setFetchMode(PDO::FETCH_ASSOC);
echo '<table border="1" >';
echo "<th>編號</th>";
echo "<th>姓名</th>";
echo "<th>地址</th>";
echo "<th>電話</th>";
echo "<th>郵箱</th>";
$allRows = $stmt->fetchAll();
foreach($allRows as $row){
    echo '<tr>';
    echo '<td>'.$row['uid'].'</td>';
    echo '<td>'.$row['name'].'</td>';
    echo '<td>'.$row['address'].'</td>';
    echo '<td>'.$row['phone'].'</td>';
    echo '<td>'.$row['email'].'</td>';
    echo '</tr>';
}
echo '</table>';

bindColumn()

  使用該方法能夠將一個列和一個指定的變量名綁定,這樣在每次使用fetch()方法獲取各行記錄時,會自動將相應的列值賦給該變量,但必須是在fetch()方法的第一個參數設置爲PDO::FETCH_BOTH值時。bindColumn()方法的原型以下所示:

bindColumn(mixed column,mixed $param[,int type]);//設置綁定列值到變量上

  第一個參數column爲必選項,可使用整數的列偏移位置索引(索引值從1開始),或是列的名稱字符串。第二個參數param也是必選項,須要傳遞一個引用,因此必須提供一個相應的變量名。第三個參數type是可選項,經過設置變量的類型來限制變量值,該參數支持的值和介紹bindParam()方法時提供的同樣

<?php
try {
    //建立對象
    $dbh = new PDO("mysql:host=localhost;dbname=testdb", "root", "***");
}catch(PDOException $e) {
    echo "數據庫鏈接失敗:".$e->getMessage();
    exit;
}
$query = "SELECT * FROM contactInfo";
$stmt = $dbh->prepare($query);
$stmt->execute();
$stmt->bindColumn(1,$uid);
$stmt->bindColumn(2,$name);
$stmt->bindColumn(3,$departmentID);
$stmt->bindColumn('address',$address);
$stmt->bindColumn('phone',$phone);
$stmt->bindColumn(6,$email);

$stmt->setFetchMode(PDO::FETCH_ASSOC);
echo '<table border="1" >';
echo "<th>編號</th>";
echo "<th>姓名</th>";
echo "<th>部門</th>";
echo "<th>地址</th>";
echo "<th>電話</th>";
echo "<th>郵箱</th>";
while($stmt->fetch()){
    echo '<tr>';
    echo '<td>'.$uid.'</td>';
    echo '<td>'.$name.'</td>';
    echo '<td>'.$departmentID.'</td>';
    echo '<td>'.$address.'</td>';
    echo '<td>'.$phone.'</td>';
    echo '<td>'.$email.'</td>';
    echo '</tr>';
}
echo '</table>';
?>

  除了能夠經過上面幾種方式獲取數據表中記錄信息外,還可使用PDOStatement類對象的columnCount()方法獲取數據表中字段的數量,而且能夠經過PDOStatement類對象的getColumnMeta()方法獲取具體列的屬性信息

PDOStatement::getColumnMeta

  PDOStatement::getColumnMeta — 返回結果集中一列的元數據。參數column表示結果集中以0開始索引的列

array PDOStatement::getColumnMeta ( int $column )
$query = "SELECT * FROM contactInfo";
$stmt = $dbh->prepare($query);
$stmt->execute();
echo $stmt->columnCount();//6
/*
array (size=7)
  'native_type' => string 'INT24' (length=5)
  'pdo_type' => int 2
  'flags' => 
    array (size=2)
      0 => string 'not_null' (length=8)
      1 => string 'primary_key' (length=11)
  'table' => string 'contactInfo' (length=11)
  'name' => string 'uid' (length=3)
  'len' => int 8
  'precision' => int 0
 */
var_dump($stmt->getColumnMeta(0));

 

大數據對象

  在進行項目開發時,有時會須要在數據庫中在存儲「大型」數據。大型對象能夠是文本數據,也能夠是二進制的圖片、電影等。PDO容許在bindParam()或bindColumn()調用中經過使用PDO::PARAM_LOB類型代碼來使用大型數據類型。PDO::PARAM_LOB告訴PDO將數據映射爲流,因此可使用PHP中的文件處理函數來操縱這樣的數據

  下面將上傳的圖像插入到一個數據庫

    $stmt =$dbh->prepare("insert into images(mimetype, data) values(?, ?)");
    $stmt->bindParam(1, $_FILES['pic']['type']);
    $fp = fopen($_FILES['pic']['tmp_name'], "rb");
    //直接使用文件資源就能夠入庫,而不用讀出文件,再插入
    $stmt->bindparam(2, $fp, PDO::PARAM_LOB);
    $stmt->execute();
    fclose($fp);

  下面從數據庫中讀出一幅圖像

    $stmt = $dbh->prepare("select mimetype, data from images where id=?");
    $stmt -> execute(array(1));
    list($mimetype, $data) = $stmt->fetch(PDO::FETCH_NUM);
    header("Content-Type: {$mimetype}");
    echo $data;
相關文章
相關標籤/搜索