PHP之PDO預處理語句操作資料庫
前面的話
本來要把預處理語句和前面的基礎操作寫成一篇的。但是,由於部落格園的限制,可能是因為長度超出,儲存時總是報錯,於是再開一篇。另一方面,相較於前面的exec()和query()語句來說,預處理語句更加常用
定義
在生成網頁時,許多PHP指令碼通常都會執行除引數之外,其他部分完全相同的查詢語句,針對這種重複執行一個查詢,每次迭代使用不同的引數情況,PDO提供了一種名為預處理語句(prepared statement)的機制。它可以將整個SQL命令向資料庫伺服器傳送一次,以後只有引數發生變化,資料庫伺服器只需對命令的結構做一次分析就夠了,即編譯一次,可以多次執行。會在伺服器上快取查詢的語句和執行過程,而只在伺服器和客戶端之間傳輸有變化的列值,以此來消除這些額外的開銷。這不僅大大減少了需要傳輸的資料量,還提高了命令的處理效率。可以有效防止SQL注入,在執行單個查詢時快於直接使用query()或exec()的方法,速度快且安全,推薦使用
PDO對預處理語句的支援需要使用PDOStatement類物件,但該類的物件並不是通過NEW關鍵字例項化出來的,而是通過執行PDO物件的prepare()方法,在資料庫伺服器中準備好一個預處理的SQL語句後直接返回的。如果通過之前執行PDO物件的query()方法返回的PDOStatement類物件,只代表的是一個結果集物件。而如果通過執行PDO物件中的prepare()方法產生的PDOStatement類物件,則為一個查詢物件,能定義和執行引數化的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()的原型如下所示:
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] => [email protected] [4] => [email protected] )
print_r($stmt->fetch());
echo "<br>";
//Array ( [uid] => 2 [0] => 2 [name] => 李四 [1] => 李四 [address] => 朝陽 [2] => 朝陽 [phone] => 123456789 [3] => 123456789 [email] => [email protected] [4] => [email protected] )
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] => [email protected] )
Array ( [0] => 2 [1] => 李四 [2] => 朝陽 [3] => 123456789 [4] => [email protected] )
Array ( [0] => 3 [1] => 王五 [2] => 海淀 [3] => 15011113456 [4] => [email protected] )
Array ( [0] => 4 [1] => 趙四 [2] => 海淀 [3] => 123456789 [4] => [email protected] )
Array ( [0] => 5 [1] => 諸葛 [2] => [3] => 120120120 [4] => [email protected] )
Array ( [0] => 6 [1] => 天使 [2] => [3] => 222 [4] => [email protected] )
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] => [email protected] [4] => [email protected] ) [1] => Array ( [uid] => 2 [0] => 2 [name] => 李四 [1] => 李四 [address] => 朝陽 [2] => 朝陽 [phone] => 123456789 [3] => 123456789 [email] => [email protected] [4] => [email protected] ) [2] => Array ( [uid] => 3 [0] => 3 [name] => 王五 [1] => 王五 [address] => 海淀 [2] => 海淀 [phone] => 15011113456 [3] => 15011113456 [email] => [email protected] [4] => [email protected] ) [3] => Array ( [uid] => 4 [0] => 4 [name] => 趙四 [1] => 趙四 [address] => 海淀 [2] => 海淀 [phone] => 123456789 [3] => 123456789 [email] => [email protected] [4] => [email protected] ) [4] => Array ( [uid] => 5 [0] => 5 [name] => 諸葛 [1] => 諸葛 [address] => [2] => [phone] => 120120120 [3] => 120120120 [email] => [email protected] [4] => [email protected] ) [5] => Array ( [uid] => 6 [0] => 6 [name] => 天使 [1] => 天使 [address] => [2] => [phone] => 222 [3] => 222 [email] => [email protected] [4] => [email protected] ) [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)
=> string 'not_null' (length=8)
=> 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;
相關推薦
PHP之PDO預處理語句操作資料庫
前面的話 本來要把預處理語句和前面的基礎操作寫成一篇的。但是,由於部落格園的限制,可能是因為長度超出,儲存時總是報錯,於是再開一篇。另一方面,相較於前面的exec()和query()語句來說,預處理語句更加常用 定義 在生成網頁時,許多PHP指令碼通常
PHP基礎知識之————PDO預處理語句
轉載處:http://www.cnblogs.com/xiaohuochai/p/6133353.html 定義 在生成網頁時,許多PHP指令碼通常都會執行除引數之外,其他部分完全相同的查詢語句,針對這種重複執行一個查詢,每次迭代使用不同的引數情況,PDO提供了一種名為預處理語句(prepared st
PDO的結果集物件方法、預處理語句、資料庫連線屬性
PDO中的結果集物件方法 方法名 註釋 execute() 執行一條預處理語句 rowCount() 返回上一個SQL語句影響的行數
PDO進行sql語句預處理和操作結果集詳細介紹(二)
<span style="font-size:18px;">一:預處理語句及其繫結引數執行insert try { $pdo=new PDO("mysql:host=localhost;dbname=xsphpdb", "root", "123
PHP的預處理語句的使用
很多更成熟的資料庫都支援預處理語句的概念。什麼是預處理語句?可以把它看作是想要執行的 SQL 的一種編譯過的模板,它可以使用變數引數進行定製。預處理語句可以帶來兩大好處: • 查詢僅需解析(或預處理)一次,但可以用相同或不同的引數執行多次。當查詢準備好後,資料庫將分析、編
文本預處理常用操作
words 是我 text github tro 標點符號 != util item 這裏介紹一下文本預處理中常用的操作: 1.英文統一小寫 text = text.lower() 2.分詞 def cut(text):
PHP之PDO的使用
sql註入 log 行數 ins int images bin catch -o pdo方式連接數據庫 try{ $db = new PDO(‘mysql:host=127.0.0.1;dbname=test;port=3306;charset=utf8‘,
PHP之pdo講解
PDO 一、今日目標 1、瞭解什麼是PDO 2、掌握如何開啟PDO擴充套件 3、能夠使用PDO物件完成增刪改操作 4、能夠將異常應用到查詢中 5、利用pdo封裝一個MySQL類,類中包括增刪改查 1、PDO介紹 PDO(PHP Data Object),PHP資料物件
caffe Python API 之圖片預處理
# 設定圖片的shape格式為網路data層格式 transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape}) # 改變維度的順序,由原始圖片維度(width, height, channel)變為(channel,
Python機器學習之資料預處理
# -*- coding: utf-8 -*- """ Created on Sat Sep 29 22:39:26 2018 @author: Lxiao217 email:[email protected] """ #資料預處理 #CSV(comma-srpared values,
1. 特徵工程之特徵預處理
1. 前言 “資料決定了機器學習的上限,而演算法只是儘可能逼近這個上限”,這裡的資料指的就是經過特徵工程得到的資料。特徵工程指的是把原始資料轉變為模型的訓練資料的過程,它的目的就是獲取更好的訓練資料特徵,使得機器學習模型逼近這個上限。特徵工程能使得模型的效能得到提升,有時甚至在簡單的模型上也能取得不錯的效果
Hibernate使用hql語句操作資料庫
使用hql語句,對資料庫進行批量查詢、條件查詢、分頁查詢 package com.kd.test; import java.util.List; import org.hibernate.Session; import org.hibernate.SessionFactory; import
機器學習實踐(四)—sklearn之特徵預處理
一、特徵預處理概述 什麼是特徵預處理 # scikit-learn的解釋 provides several common utility functions and transformer classes to change raw feature vectors into
資料分析與挖掘之資料預處理
目錄 資料整合 簡單變換 資料整合 #資料整合 import numpy a=numpy.array([[1,5,6],[9,4,3]]) b=numpy.array([[6,36,7],[2,3,39]]) c=numpy.conca
PDO預處理
1.引數以?替代 <?php header('content-type:text/html;charset=utf-8'); $dsn='mysql:host=localhost;dbname=test'; $pdo=new PDO($dsn,'root',''); $pdo-&
043:Django使用原生SQL語句操作資料庫
Django使用原生SQL語句操作資料庫 Django配置連線資料庫: 在操作資料庫之前,首先先要連線資料庫。這裡我們以配置 MySQL 為例來講解。 Django 連線資料庫,不需要單獨的建立一個連線物件。只需要在 settings.py 檔案中做好資料庫相關的配置就可以了。示例程式碼如下:
機器學習之 資料預處理(sklearn preprocessing)
資料預處理(data preprocessing)是指在主要的處理以前對資料進行的一些處理。如對大部分地球物理面積性觀測資料在進行轉換或增強處理之前,首先將不規則分佈的測網經過插值轉換為規則網的處理,以利於計算機的運算。另外,對於一些剖面測量資料,如地震資料預處理有垂直疊加、
第十招 PHP之表單處理
表單中的輸入框型別 當輸入的內容為普通文字時,type的值為text <input type="text" name="user"> 當輸入的內容為密碼時,type的值為password <input type="password" name="pwd">
機器學習特徵工程之特徵預處理
特徵預處理是什麼? 通過特定的統計方法(數學方法)講資料轉換成演算法要求的資料。 數值型資料: 歸一化 標準化 缺失值 類別型資料:one-hot編碼 時間型別:時間的切分 特徵選擇的意義 在對資料進行異常值、缺失值、資料轉換等處理後,我們