[TOC]
****
## 1 PDO的意義
PDO(php data object)**PHP數據對象擴展**為數據庫定義了一個輕量級的一致接口。
PDO擴展自身并不能實現任何數據庫功能,必須使用**具體數據庫的PDO驅動**來訪問數據庫服務,實現PDO接口的每個數據庫驅動可以將特定數據庫的訪問作為標準擴展功能。
PDO提供了一個**數據訪問**抽象層,意味著不管使用哪種數據庫,都可以使用相同的函數來查詢和獲取數據。通常用用作實現數據庫訪問的底層。
在PHP5.0中PDO是作為一個擴展使用,在PHP5.1后開始附帶PDO擴展。
## 2 PDO的使用
### 2-1 PDO連接數據庫
>[info] 1 可以通過創建PDO基類的實例來連接數據庫。構造函數接受用于指定數據庫源以及用戶名和密碼等參數
~~~
;PDO數據庫連接
$dbh = new PDO ( 'mysql:host=localhost;dbname=test' , $user , $pass );
~~~
>[info] 2 可以使用PDOException處理連接錯誤。
~~~
;PDO數據連接異常處理
try {
$dbh = new PDO ( 'mysql:host=localhost;dbname=test' , $user , $pass );
foreach( $dbh -> query ( 'SELECT * from FOO' ) as $row ) {
print_r ( $row );
}
$dbh = null ;
} catch ( PDOException $e ) {
print "Error!: " . $e -> getMessage () . "<br/>" ;
die();
}
~~~
>[info] 3 構造函數中可以攜帶不同參數實現不同的連接,下面使用參數實現持久化連接
~~~
;使用PDO參數實現持久化連接
$dbh = new PDO ( 'mysql:host=localhost;dbname=test' , $user , $pass , array(
PDO :: ATTR_PERSISTENT => true
));
~~~
>[info] 4 連接成功后,返回一個PDO類的實例給腳本。可以調用PDO實例的方法實現對數據庫的操作
>[info] 此連接在**PDO對象的生存周期中保持活動**。關閉連接,只需要銷毀對象并確保所有剩余到它的引用到被刪除,可以通過賦值NULL給對象變量。
>[info] 如果沒有明確刪除,則會在PHP腳本結束時自動關閉連接
~~~
;關閉PDO連接
//創建數據庫連接
$dbh = new PDO ( 'mysql:host=localhost;dbname=test' , $user , $pass );
//操作數據庫
//操作數據庫
//關閉數據庫連接
$dbh = null ;
~~~
### 2-2 PDO預處理語句與存儲過程
>[info] 1 PDO可以實現數據庫預處理語句。預處理器語句看做待運行的SQL語句的一種模板,可以使用變量參數進行綁定處理。
~~~
;使用占位符生成預處理語句準備SQL語句
$stmt = $dbh -> prepare ( "INSERT INTO REGISTRY (name, value) VALUES (:name, :value)" );
;:name和:value作為命名占位符
$stmt -> bindParam ( ':name' , $name );
$stmt -> bindParam ( ':value' , $value );
// 插入一行
$name = 'one' ;
$value = 1 ;
$stmt -> execute ();
// 用不同的值插入另一行
$name = 'two' ;
$value = 2 ;
$stmt -> execute ();
~~~
~~~
;使用?占位符生成SQL預處理語句
$stmt = $dbh -> prepare ( "INSERT INTO REGISTRY (name, value) VALUES (?, ?)" );
$stmt -> bindParam ( 1 , $name );
$stmt -> bindParam ( 2 , $value );
// 插入一行
$name = 'one' ;
$value = 1 ;
$stmt -> execute ();
// 用不同的值插入另一行
$name = 'two' ;
$value = 2 ;
$stmt -> execute ();
~~~
>[info] 2 預處理語句可以帶來兩大好處
>[info] (1) 查詢僅僅需要解析或預處理一次,但可以使用相同或不同的參數執行多次。
>[info] 當查詢準備后,數據庫將分析,編譯和優化執行該查詢的計劃。對于復雜的查詢,此過程需要花費較多時間,如果需要以不同參數多次重復相同的查詢,該過程將大大降低應用程序的速度
>[info] 通過預處理語句,可以避免重復分析編譯優化周期,因此預處理語句占用更少的資源,運行更快
>[info] (2)提供給預處理語句的參數不需要使用引號括起來,驅動程序會自動處理。如果應用程序只需要處理預處理語句,可以確保不會發生SQL注入。(手冊照搬)
~~~
;預處理語句獲取數據
$stmt = $dbh -> prepare ( "SELECT * FROM REGISTRY where name = ?" );
if ( $stmt -> execute (array( $_GET [ 'name' ]))) {
while ( $row = $stmt -> fetch ()) {
print_r ( $row );
}
}
~~~
>[info] 3 數據庫驅動支持下,應用程序還可以綁定輸出和輸入參數,輸出參數通常用于從存儲過程取值。輸出參數使用起來比輸入參數復雜一些,綁定一個輸出參數時,必須知道給的參數的長度。
~~~
$stmt = $dbh -> prepare ( "CALL sp_returns_string(?)" );
$stmt -> bindParam ( 1 , $return_value , PDO :: PARAM_STR , 4000 );
// 調用存儲過程
$stmt -> execute ();
print "procedure returned $return_value \n" ;
~~~
>[info] 4 可以指定同時具有輸入和輸出值的參數,當存儲過程返回時,保存輸出值
~~~
$stmt = $dbh -> prepare ( "CALL sp_takes_string_returns_string(?)" );
$value = 'hello' ;
$stmt -> bindParam ( 1 , $value , PDO :: PARAM_STR | PDO :: PARAM_INPUT_OUTPUT , 4000 );
// 調用存儲過程
$stmt -> execute ();
print "procedure returned $value \n" ;
~~~
>[info] 5 注意占位符對于SQL語句完整性的補充
~~~
$stmt = $dbh -> prepare ( "SELECT * FROM REGISTRY where name LIKE '%?%'" );
$stmt -> execute (array( $_GET [ 'name' ]));
// 占位符必須保證SQL語句完整
$stmt = $dbh -> prepare ( "SELECT * FROM REGISTRY where name LIKE ?" );
$stmt -> execute (array( "% $_GET [ name ] %" ));
~~~
### 2-3 PDO事務和自動提交
>[info] 1 事務可以看做多條SQL語句的順序組合。事務通常用來實現數據庫的ACID特性。事務操作可以根據請求請求整體執行,或者根據請求自動撤銷
>[info] 2 事務通常把一些語句準備好同時生效實現的,這樣做的好處可以大大提高更改效率。因此腳本更快,更健壯
>[info] 3 事務需要數據庫支持,但是并非每種數據庫都支持事務,當第一次打開連接時,PDO默認在自動提交模式下運行。自動提交下運行的每個查詢都有它自己的事務,如果數據庫不支持事務,則沒有,
>[info] 4 如果需要一個事務,則必須使用PDO::beginTransaction()方法取得,如果底層取得不支持事務,會拋出一個PDOException依次。
>[info] 5 開始事務后,可以使用PDO::commit()或者PDO::rollBack()完成,取決于事務中的代碼是否允許成功
>[info] 6 事務查詢與復雜查詢對比,事務更具有數據庫的一致性。
~~~
;PDO事務的簡單使用
try {
$dbh = new PDO ( 'odbc:SAMPLE' , 'db2inst1' , 'ibmdb2' ,
array( PDO :: ATTR_PERSISTENT => true ));
echo "Connected\n" ;
} catch ( Exception $e ) {
die( "Unable to connect: " . $e -> getMessage ());
}
try {
$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 ();
}
~~~
### 2-4 PDO大對象
### 2-5 PDO錯誤和錯誤處理
>[info] PDO提供了三種不同的錯誤處理模式,
>[info] (1) PDO::ERRMODE_SILENT 默認模式,可以簡單地設置錯誤碼,使用PDO::errorCode()和PDO::errorInfo()方法來檢查語句和數據庫對象。
>[info] 如果錯誤是由于對語句對象的調用而產生的,那么可以調用對象的PDOStatement::errorCode()和PDOStatement::errorInfo()方法。如果錯誤由于調用數據庫對象而產生的,可以在數據庫對象上調用上述兩個方法
>[info] (2) PDO::ERRMODE_WARNING
除了設置錯誤碼后,PDO還將發出一條傳統的E_WARNING信息。如果只是想看看發生的問題而且不中斷應用程序的流程,此設置經常在調試/測試期間非常有用
>[info] (3) PDO::ERRMODE_EXCEPTION
除了設置錯誤碼后,PDO還將拋出一個PDOException異常類并設置其屬性來反射錯誤碼和錯誤信息,在調試期間非常有用,會有效地放大腳本中產生錯誤的點,從而可以非常快速地支持代碼中問題的潛在區域
>[info] 異常模式可以清晰地構建自己的錯誤處理,避免傳統模式中異常模式的處理組織方式
~~~
;創建PDO實例設置錯誤模式
$dsn = 'mysql:dbname=testdb;host=127.0.0.1' ;
$user = 'dbuser' ;
$password = 'dbpass' ;
try {
$dbh = new PDO ( $dsn , $user , $password );
$dbh -> setAttribute ( PDO :: ATTR_ERRMODE , PDO :: ERRMODE_EXCEPTION );
} catch ( PDOException $e ) {
echo 'Connection failed: ' . $e -> getMessage ();
}
~~~
~~~
;在構造函數中設置錯誤模式
$dsn = 'mysql:dbname=test;host=127.0.0.1' ;
$user = 'googleguy' ;
$password = 'googleguy' ;
try {
$dbh = new PDO ( $dsn , $user , $password , array( PDO :: ATTR_ERRMODE => PDO :: ERRMODE_WARNING ));
} catch ( PDOException $e ) {
echo 'Connection failed: ' . $e -> getMessage ();
exit;
}
$dbh -> query ( "SELECT wrongcolumn FROM wrongtable" );
~~~
## 3 PDO類(PHP和數據庫服務之間的連接類)
### 1 __construct()構造函數
~~~
PDO::__construct ( string $dsn [, string $username [, string $password [, array $driver_options ]]] )
~~~
> $dsn: 數據源名稱或叫做DSN,包含了請求連接到數據庫的信息,通常一個DSN由PDO驅動名,緊隨其后的冒號以及具體的PDO驅動的連接語法組成,支持三種不同方式的DSN
>$username: DSN字符串中的用戶名
>$password: DSN字符串中的密碼
>driver_options: 數據庫連接鍵值對參數
### 2 setAttribute() PDO屬性設置
~~~
bool PDO::setAttribute ( int $attribute , mixed $value )
~~~
>常見可設置數據庫屬性
> $attribute PDO::ATTR_CASE
>> 強制列名為指定的大小寫。
>> PDO::CASE_LOWER:強制列名小寫
>> PDO::CASE_UPPER:強制列名大寫。
>> PDO::CASE_NATURAL:保留數據庫驅動返回的列名
> $attribute PDO::ATTR_ERRMODE
>> 錯誤報告
>> PDO::ERRMODE_SILENT: 僅僅設置錯誤代碼
>> PDO::ERRMODE_WARNING: 引發警告信息
>> PDO::ERRMODE_EXCEPTION: 拋出異常
> $attribue PDO::ATTR_ORACLE_NULLS
>> 空字符串和NULL的轉換
>> PDO::NULL_NATURAL: 不轉換
>> PDO::NULL_EMPTY_STRING:空字符串轉換為NULL
>> PDO::NULL_TO_STRING:NULL轉換為空字符串
> $attribute PDO::ATTR_STRINGIFY_FETCHES
>> 是否將數字值轉換為字符串
>> true
>> false
> $attribute PDO::ATTR_STATEMENT_CLASS
>> 設置從PDOStatement派生的用戶提供的語句類,
>> 使用array(string 類名,array(mixed 構造函數的參數))
> $attribue PDO::ATTR_TIMEOUT
>> 設置超時的秒數。
> $attribute PDO::ATTR_AUTOCOMMIT
>> 設置是否自動提交每個單獨的語句
> $attribue PDO::ATTR_EMULATE_PREPARES
>> 開啟或關閉預處理語句的模擬
>> true 強制PDO使用模擬預處理語句
>> false 本地預處理語句
> $attribute PDO::MYSQL_ATTR_USE_BUFFERED_QUERY
>> 是否使用緩沖查詢
>> Mysql中可以使用
> $attribute PDO::ATTR_DEFAULT_FETCH_MODE
>> 返回結果的模式
>> 作為PDOStatement::fetch()默認值
> 設置數據庫連接屬性
### 3 getAttribute() PDO屬性獲取
~~~
mixed PDO::getAttribute ( int $attribute )
~~~
> $attribute 返回數據庫連接屬性,下列屬性的一個
>> PDO::ATTR_AUTOCOMMIT
>> PDO::ATTR_CASE
>> PDO::ATTR_CLIENT_VERSION
>> PDO::ATTR_CONNECTION_STATUS
>> PDO::ATTR_DRIVER_NAME
>> PDO::ATTR_ERRMODE
>> PDO::ATTR_ORACLE_NULLS
>> PDO::ATTR_PERSISTENT
>> PDO::ATTR_PREFETCH
>> PDO::ATTR_SERVER_INFO
>> PDO::ATTR_SERVER_VERSION
>> PDO::ATTR_TIMEOUT
> 成功調用返回請求的PDO屬性值,不成功返回null
~~~
$conn = new PDO ( 'odbc:sample' , 'db2inst1' , 'ibmdb2' );
$attributes = array(
"AUTOCOMMIT" , "ERRMODE" , "CASE" , "CLIENT_VERSION" , "CONNECTION_STATUS" ,
"ORACLE_NULLS" , "PERSISTENT" , "PREFETCH" , "SERVER_INFO" , "SERVER_VERSION" ,
"TIMEOUT"
);
foreach ( $attributes as $val ) {
echo "PDO::ATTR_ $val : " ;
echo $conn -> getAttribute ( constant ( "PDO::ATTR_ $val " )) . "\n" ;
}
~~~
### 4 getAvailableDrivers() 返回可用驅動的數組
~~~
static array PDO::getAvailableDrivers ( void )
~~~
> 返回在PDO::__construct()參數DSN中的PDO可以驅動類型
~~~
print_r ( PDO :: getAvailableDrivers ());
~~~
輸出:
~~~
Array
(
[0] => mysql
[1] => sqlite
)
~~~
### 5 quote() 語句轉義處理
~~~
public string PDO::quote ( string $string [, int $parameter_type = PDO::PARAM_STR ] )
~~~
> $string: 待轉移語句
> $paratemter_type : 轉義風格?
~~~
;簡單語句轉義
$conn = new PDO ( 'sqlite:/home/lynn/music.sql3' );
$string = 'Nice' ;
print "Unquoted string: $string \n" ;
print "Quoted string: " . $conn -> quote ( $string ) . "\n" ;
~~~
輸出
~~~
Unquoted string: Nice
Quoted string: 'Nice'
~~~
~~~
;危險語句轉義
$conn = new PDO ( 'sqlite:/home/lynn/music.sql3' );
$string = 'Naughty \' string' ;
print "Unquoted string: $string \n" ;
print "Quoted string:" . $conn -> quote ( $string ) . "\n" ;
~~~
輸出
~~~
Unquoted string: Naughty ' string
Quoted string: 'Naughty '' string'
~~~
~~~
;復雜語句轉義
$conn = new PDO ( 'sqlite:/home/lynn/music.sql3' );
$string = "Co'mpl''ex \"st'\"ring" ;
print "Unquoted string: $string \n" ;
print "Quoted string: " . $conn -> quote ( $string ) . "\n" ;
~~~
輸出
~~~
Unquoted string: Co'mpl''ex "st'"ring
Quoted string: 'Co''mpl''''ex "st''"ring'
~~~
### 6 prepare() 準備待執行SQL語句
~~~
public PDOStatement PDO::prepare ( string $statement [, array $driver_options = array() ] )
~~~
> $statement:sql語句
> $driver_options:數據庫驅動參數
> 返回待執行的PDOStatement對象
~~~
;命名占位符sql語句生成
$sql = 'SELECT name, colour, calories
FROM fruit
WHERE calories < :calories AND colour = :colour' ;
$sth = $dbh -> prepare ( $sql , array( PDO :: ATTR_CURSOR => PDO :: CURSOR_FWDONLY ));
$sth -> execute (array( ':calories' => 150 , ':colour' => 'red' ));
$red = $sth -> fetchAll ();
$sth -> execute (array( ':calories' => 175 , ':colour' => 'yellow' ));
$yellow = $sth -> fetchAll ();
~~~
~~~
;?占位符sql語句生成
$sth = $dbh -> prepare ( 'SELECT name, colour, calories
FROM fruit
WHERE calories < ? AND colour = ?' );
$sth -> execute (array( 150 , 'red' ));
$red = $sth -> fetchAll ();
$sth -> execute (array( 175 , 'yellow' ));
$yellow = $sth -> fetchAll ();
~~~
### 7 exec() 執行一個SQL語句,返回受此語句影響的行數
~~~
int PDO::exec ( string $statement )
~~~
> $statement 被預處理和執行的SQL語句
> 單獨函數中執行一條SQL語句,返回受此語句影響的行數
~~~
$db -> exec () or die( print_r ( $db -> errorInfo (), true ));
~~~
~~~
$dbh = new PDO ( 'odbc:sample' , 'db2inst1' , 'ibmdb2' );
$count = $dbh -> exec ( "DELETE FROM fruit WHERE colour = 'red'" );
print( "Deleted $count rows.\n" );
~~~
### 8 query() 執行SQL語句,返回PDOStatement對象
~~~
public PDOStatement PDO::query ( string $statement )
public PDOStatement PDO::query ( string $statement , int $PDO::FETCH_COLUMN , int $colno )
public PDOStatement PDO::query ( string $statement , int $PDO::FETCH_CLASS , string $classname , array $ctorargs )
public PDOStatement PDO::query ( string $statement , int $PDO::FETCH_INTO , object $object )
~~~
> $statement:待執行sql語句
~~~
function getFruit ( $conn ) {
$sql = 'SELECT name, color, calories FROM fruit ORDER BY name' ;
foreach ( $conn -> query ( $sql ) as $row ) {
print $row [ 'name' ] . "\t" ;
print $row [ 'color' ] . "\t" ;
print $row [ 'calories' ] . "\n" ;
}
}
~~~
輸出
~~~
apple red 150
banana yellow 250
kiwi brown 75
lemon yellow 25
orange orange 300
pear green 150
watermelon pink 90
~~~
### 9 beginTransaction 啟動事務
~~~
bool PDO::beginTransaction ( void )
~~~
> 關閉自動提交,進入事務的手動提交模式
~~~
/* 開始一個事務,關閉自動提交 */
$dbh -> beginTransaction ();
/* 更改數據庫架構及數據 */
$sth = $dbh -> exec ( "DROP TABLE fruit" );
$sth = $dbh -> exec ( "UPDATE dessert
SET name = 'hamburger'" );
/* 識別出錯誤并回滾更改 */
$dbh -> rollBack ();
/* 數據庫連接現在返回到自動提交模式 */
~~~
### 10 commint() 手動提交事務
~~~
bool PDO::commit ( void )
~~~
> 事務中進行手動提交,返回到自動提交模式
~~~
/* 開始一個事務,關閉自動提交 */
$dbh -> beginTransaction ();
/* 在全有或全無的基礎上插入多行記錄(要么全部插入,要么全部不插入) */
$sql = 'INSERT INTO fruit
(name, colour, calories)
VALUES (?, ?, ?)' ;
$sth = $dbh -> prepare ( $sql );
foreach ( $fruits as $fruit ) {
$sth -> execute (array(
$fruit -> name ,
$fruit -> colour ,
$fruit -> calories ,
));
}
/* 提交更改 */
$dbh -> commit ();
/* 現在數據庫連接返回到自動提交模式 */
~~~
~~~
/* 開始一個事務,關閉自動提交 */
$dbh -> beginTransaction ();
/* Change the database schema */
$sth = $dbh -> exec ( "DROP TABLE fruit" );
/* 更改數據庫架構 */
$dbh -> commit ();
/* 現在數據庫連接返回到自動提交模式 */
~~~
### 11 rollBack() 回滾一個事務
~~~
回滾由PDO::beginTransaction() 發起的當前事務中的手動提交
設置成自動提交模式,的回滾事務后恢復自動提交模式
包括 MySQL 在內的一些數據庫, 當在一個事務內有類似刪除或創建數據表等 DLL 語句時,會自動導致一個隱式地提交。隱式地提交將無法回滾此事務范圍內的任何更改
~~~
~~~
;在 MySQL 中,DROP TABLE 語句自動提交事務,因此在此事務內的任何更改都不會被回滾。
/* 開始一個事務,關閉自動提交 */
$dbh -> beginTransaction ();
/* 更改數據庫架構和數據 */
$sth = $dbh -> exec ( "DROP TABLE fruit" );
$sth = $dbh -> exec ( "UPDATE dessert
SET name = 'hamburger'" );
/* 識別錯誤且回滾更改 */
$dbh -> rollBack ();
/* 此時數據庫連接恢復到自動提交模式 */
~~~
### 12 inTransaction() 檢查是否在一個事務內
~~~
bool PDO::inTransaction ( void )
~~~
> 檢查驅動內的一個事務是否處于激活
### 13 lastInsertId() 返回最后插入行的ID或序列值
~~~
string PDO::lastInsertId ([ string $name = NULL ] )
~~~
> 返回ID對應的序列對象的名稱
>>如果沒有為參數 name 指定序列名稱, PDO::lastInsertId() 則返回一個表示最后插入數據庫那一行的行ID的字符串。
>>如果為參數 name 指定了序列名稱, PDO::lastInsertId() 則返回一個表示從指定序列對象取回最后的值的字符串。
>>如果當前 PDO 驅動不支持此功能,則 PDO::lastInsertId() 觸發一個 IM001 SQLSTATE 。
### 14 errorCode() 獲取上次數據庫操作錯誤碼
~~~
mixed PDO::errorCode ( void )
~~~
> 返回一個SQLSTATE說明碼,一個由5個字母或數字組成的SQL標準定義的標識符
~~~
$dbh -> exec ( "INSERT INTO bones(skull) VALUES ('lucy')" );
echo "\nPDO::errorCode(): " ;
print $dbh -> errorCode ();
~~~
輸出
~~~
PDO::errorCode(): 42S02
~~~
### 15 errorInfo() 獲取上次數據庫操作錯誤信息
~~~
public array PDO::errorInfo ( void )
~~~
> 返回錯誤信息數組
>> SQLSTATE
>> Driver error code
>> Driver error message
~~~
$stmt = $dbh -> prepare ( 'bogus sql' );
if (! $stmt ) {
echo "\nPDO::errorInfo():\n" ;
print_r ( $dbh -> errorInfo ());
}
~~~
輸出
~~~
PDO::errorInfo():
Array
(
[0] => HY000
[1] => 1
[2] => near "bogus": syntax error
)
~~~
## 4 PDOStatment類(代表預處理語句,執行后保存相關結果集)
### 4-1 $queryString 成員變量
> 代表查詢字符串內容
### 4-2 bindParam() 綁定參數到預處理語句
~~~
bool PDOStatement::bindParam ( mixed $parameter , mixed &$variable [, int $data_type = PDO::PARAM_STR [, int $length [, mixed $driver_options ]]] )
~~~
> $paramter 參數標識符 命名占位符:name。問號占位符使用以1為開始索引的參數位置
> $varibale 綁定到參數的變量名
> $data_type 指定參數的類型
> $length 數據類型的長度
> $driver_options 驅動配置參數
> 綁定一個PHP變量到用作預處理的SQL語句中的對應命名占位符或問號占位符。 不同于 PDOStatement::bindValue() ,此變量作為引用被綁定,并只在 PDOStatement::execute() 被調用的時候才取其值。
> 大多數參數是輸入參數,即,參數以只讀的方式用來建立查詢。一些驅動支持調用存儲過程并作為輸出參數返回數據,一些支持作為輸入/輸出參數,既發送數據又接收更新后的數據。
~~~
/* 通過綁定的 PHP 變量執行一條預處理語句 */
$calories = 150 ;
$colour = 'red' ;
$sth = $dbh -> prepare ( 'SELECT name, colour, calories
FROM fruit
WHERE calories < :calories AND colour = :colour' );
$sth -> bindParam ( ':calories' , $calories , PDO :: PARAM_INT );
$sth -> bindParam ( ':colour' , $colour , PDO :: PARAM_STR , 12 );
$sth -> execute ();
~~~
~~~
/* 通過綁定的 PHP 變量執行一條預處理語句 */
$calories = 150 ;
$colour = 'red' ;
$sth = $dbh -> prepare ( 'SELECT name, colour, calories
FROM fruit
WHERE calories < ? AND colour = ?' );
$sth -> bindParam ( 1 , $calories , PDO :: PARAM_INT );
$sth -> bindParam ( 2 , $colour , PDO :: PARAM_STR , 12 );
$sth -> execute ();
~~~
~~~
/* 使用 INOUT 參數調用一個存儲過程 */
$colour = 'red' ;
$sth = $dbh -> prepare ( 'CALL puree_fruit(?)' );
$sth -> bindParam ( 1 , $colour , PDO :: PARAM_STR | PDO :: PARAM_INPUT_OUTPUT , 12 );
$sth -> execute ();
print( "After pureeing fruit, the colour is: $colour " );
~~~
### 4-3 bindValue() 綁定一個值到一個參數
~~~
bool PDOStatement::bindValue ( mixed $parameter , mixed $value [, int $data_type = PDO::PARAM_STR ] )
~~~
> $parameter:參數標識符 命名占位符:name。問號占位符使用以1為開始索引的參數位置
> $value:綁定到參數的值
> $data_type 指定參數的類型
>> PDOStatement::bindValue() ,此變量作為引用被綁定,并只在 PDOStatement::execute() 被調用的時候才取其值
~~~
/* 通過綁定的 PHP 變量執行一條預處理語句 */
$calories = 150 ;
$colour = 'red' ;
$sth = $dbh -> prepare ( 'SELECT name, colour, calories
FROM fruit
WHERE calories < :calories AND colour = :colour' );
$sth -> bindValue ( ':calories' , $calories , PDO :: PARAM_INT );
$sth -> bindValue ( ':colour' , $colour , PDO :: PARAM_STR );
$sth -> execute ();
~~~
~~~
/* 通過綁定的 PHP 變量執行一條預處理語句 */
$calories = 150 ;
$colour = 'red' ;
$sth = $dbh -> prepare ( 'SELECT name, colour, calories
FROM fruit
WHERE calories < ? AND colour = ?' );
$sth -> bindValue ( 1 , $calories , PDO :: PARAM_INT );
$sth -> bindValue ( 2 , $colour , PDO :: PARAM_STR );
$sth -> execute ();
~~~
### 4-4 bindColumn() 綁定一列到一個PHP變量
~~~
bool PDOStatement::bindColumn ( mixed $column , mixed &$param [, int $type [, int $maxlen [, mixed $driverdata ]]] )
~~~
> $column 結果集中的列號(從1開始索引)或列名。如果使用列名,注意名稱應該與由驅動返回的列名大小寫保持一致。
> $param 將綁定到列的 PHP 變量名稱
> $type 通過 PDO::PARAM_* 常量指定的參數的數據類型。
> $maxlen 預分配提示。
> $driverdata 驅動的可選參數。
~~~
;結果集輸出綁定到PHP變量
function readData ( $dbh ) {
$sql = 'SELECT name, colour, calories FROM fruit' ;
try {
$stmt = $dbh -> prepare ( $sql );
$stmt -> execute ();
/* 通過列號綁定 */
$stmt -> bindColumn ( 1 , $name );
$stmt -> bindColumn ( 2 , $colour );
/* 通過列名綁定 */
$stmt -> bindColumn ( 'calories' , $cals );
while ( $row = $stmt -> fetch ( PDO :: FETCH_BOUND )) {
$data = $name . "\t" . $colour . "\t" . $cals . "\n" ;
print $data ;
}
}
catch ( PDOException $e ) {
print $e -> getMessage ();
}
}
readData ( $dbh );
~~~
輸出
~~~
apple red 150
banana yellow 175
kiwi green 75
orange orange 150
mango red 200
strawberry red 25
~~~
### 4-5 execute() 執行PDO::prepare()生成的預處理語句
~~~
bool PDOStatement::execute ([ array $input_parameters ] )
~~~
> $input_parameters:綁定參數列表
>> 1.調用 PDOStatement::bindParam() 綁定 PHP 變量到參數標記:如果有的話,通過關聯參數標記綁定的變量來傳遞輸入值和取得輸出值
>> 2.或傳遞一個只作為輸入參數值的數組
~~~
;綁定變量到預處理語句并執行
$calories = 150 ;
$colour = 'red' ;
$sth = $dbh -> prepare ( 'SELECT name, colour, calories
FROM fruit
WHERE calories < :calories AND colour = :colour' );
$sth -> bindParam ( ':calories' , $calories , PDO :: PARAM_INT );
$sth -> bindParam ( ':colour' , $colour , PDO :: PARAM_STR , 12 );
$sth -> execute ();
~~~
~~~
/* 通過傳遞一個含有插入值的數組執行一條預處理語句 */
$calories = 150 ;
$colour = 'red' ;
$sth = $dbh -> prepare ( 'SELECT name, colour, calories
FROM fruit
WHERE calories < :calories AND colour = :colour' );
$sth -> execute (array( ':calories' => $calories , ':colour' => $colour /*
~~~
~~~
;通過傳遞一個含有插入值的數組執行一條預處理語句 */
$calories = 150 ;
$colour = 'red' ;
$sth = $dbh -> prepare ( 'SELECT name, colour, calories
FROM fruit
WHERE calories < :calories AND colour = :colour' );
$sth -> execute (array( ':calories' => $calories , ':colour' => $colour ));));
~~~
### 4-3 fetch() 從結果集中獲取下一行
~~~
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 )。
>> 1. PDO::FETCH_ASSOC:返回一個索引為結果集列名的數組
>> 2. PDO::FETCH_BOTH(默認):返回一個索引為結果集列名和以0開始的列號的數組
>> 3. PDO::FETCH_BOUND:返回 TRUE ,并分配結果集中的列值給 PDOStatement::bindColumn() 方法綁定的 PHP 變量。
>> 4. PDO::FETCH_CLASS:返回一個請求類的新實例,映射結果集中的列名到類中對應的屬性名。如果 fetch_style 包含 PDO::FETCH_CLASSTYPE(例如:PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE),則類名由第一列的值決定
>> 5. PDO::FETCH_INTO:更新一個被請求類已存在的實例,映射結果集中的列到類中命名的屬性
>> 6. PDO::FETCH_LAZY:結合使用 PDO::FETCH_BOTH 和 PDO::FETCH_OBJ,創建供用來訪問的對象變量名
>> 7. PDO::FETCH_NUM:返回一個索引為以0開始的結果集列號的數組
>> 8. 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() 前游標的位置
> 從PDOStatement::execute()執行預處理語句的結果集中獲取下一行。返回值依賴于PDO中PDO::FETCH_* 的配置
>Eg1: 使用不同的提取方式獲取行
~~~
$sth = $dbh -> prepare ( "SELECT name, colour FROM fruit" );
$sth -> execute ();
/* 運用 PDOStatement::fetch 風格 */
print( "PDO::FETCH_ASSOC: " );
print( "Return next row as an array indexed by column name\n" );
$result = $sth -> fetch ( PDO :: FETCH_ASSOC );
print_r ( $result );
print( "\n" );
print( "PDO::FETCH_BOTH: " );
print( "Return next row as an array indexed by both column name and number\n" );
$result = $sth -> fetch ( PDO :: FETCH_BOTH );
print_r ( $result );
print( "\n" );
print( "PDO::FETCH_LAZY: " );
print( "Return next row as an anonymous object with column names as properties\n" );
$result = $sth -> fetch ( PDO :: FETCH_LAZY );
print_r ( $result );
print( "\n" );
print( "PDO::FETCH_OBJ: " );
print( "Return next row as an anonymous object with column names as properties\n" );
$result = $sth -> fetch ( PDO :: FETCH_OBJ );
print $result -> NAME ;
print( "\n" );
~~~
輸出
~~~
PDO::FETCH_ASSOC: Return next row as an array indexed by column name
Array
(
[NAME] => apple
[COLOUR] => red
)PDO::FETCH_BOTH: Return next row as an array indexed by both column name and number
Array
(
[NAME] => banana
[0] => banana
[COLOUR] => yellow
[1] => yellow
)PDO::FETCH_LAZY: Return next row as an anonymous object with column names as properties
PDORow Object
(
[NAME] => orange
[COLOUR] => orange
)PDO::FETCH_OBJ: Return next row as an anonymous object with column names as properties
kiwi
~~~
> Eg2:使用可滾動游標獲取行
~~~
function readDataForwards ( $dbh ) {
$sql = 'SELECT hand, won, bet FROM mynumbers ORDER BY BET' ;
try {
$stmt = $dbh -> prepare ( $sql , array( PDO :: ATTR_CURSOR => PDO :: CURSOR_SCROLL ));
$stmt -> execute ();
while ( $row = $stmt -> fetch ( PDO :: FETCH_NUM , PDO :: FETCH_ORI_NEXT )) {
$data = $row [ 0 ] . "\t" . $row [ 1 ] . "\t" . $row [ 2 ] . "\n" ;
print $data ;
}
$stmt = null ;
}
catch ( PDOException $e ) {
print $e -> getMessage ();
}
}
function readDataBackwards ( $dbh ) {
$sql = 'SELECT hand, won, bet FROM mynumbers ORDER BY bet' ;
try {
$stmt = $dbh -> prepare ( $sql , array( PDO :: ATTR_CURSOR => PDO :: CURSOR_SCROLL ));
$stmt -> execute ();
$row = $stmt -> fetch ( PDO :: FETCH_NUM , PDO :: FETCH_ORI_LAST );
do {
$data = $row [ 0 ] . "\t" . $row [ 1 ] . "\t" . $row [ 2 ] . "\n" ;
print $data ;
} while ( $row = $stmt -> fetch ( PDO :: FETCH_NUM , PDO :: FETCH_ORI_PRIOR ));
$stmt = null ;
}
catch ( PDOException $e ) {
print $e -> getMessage ();
}
}
print "Reading forwards:\n" ;
readDataForwards ( $conn );
print "Reading backwards:\n" ;
readDataBackwards ( $conn );
~~~
輸出
~~~
Reading forwards:
21 10 5
16 0 5
19 20 10Reading backwards:
19 20 10
16 0 5
21 10 5
~~~
### 4-5 fetchAll() 返回結果集中所有行的數組
~~~
array PDOStatement::fetchAll ([ int $fetch_style [, mixed $fetch_argument [, array $ctor_args = array() ]]] )
~~~
> $fetch_style 結果集類型
> $fetch_argument 結果列參數
>> PDO::FETCH_COLUMN :返回指定以0開始索引的列。
>> PDO::FETCH_CLASS :返回指定類的實例,映射每行的列到類中對應的屬性名。
>> PDO::FETCH_FUNC :將每行的列作為參數傳遞給指定的函數,并返回調用函數后的結果。
> $ctor_args 自定義類的構造函數的參數。
>> 當 fetch_style 參數為 PDO::FETCH_CLASS 時,自定義類的構造函數的參數。
> 返回包含結果集中所有剩余行的數組。此數組的每一行要么是一個列值的數組,要么是屬性對應每個列名的一個對象。
> 使用此方法獲取大結果集將導致系統負擔加重且可能占用大量網絡資源。與其取回所有數據后用PHP來操作,倒不如考慮使用數據庫服務來處理結果集。例如,在取回數據并通過PHP處理前,在 SQL 中使用 WHERE 和 ORDER BY 子句來限定結果。
~~~
;獲取結果集中所有剩余的行
$sth = $dbh -> prepare ( "SELECT name, colour FROM fruit" );
$sth -> execute ();
/* 獲取結果集中所有剩余的行 */
print( "Fetch all of the remaining rows in the result set:\n" );
$result = $sth -> fetchAll ();
print_r ( $result );
~~~
輸出
~~~
Fetch all of the remaining rows in the result set:
Array
(
[0] => Array
(
[NAME] => pear
[0] => pear
[COLOUR] => green
[1] => green
) [1] => Array
(
[NAME] => watermelon
[0] => watermelon
[COLOUR] => pink
[1] => pink
))
~~~
~~~
;獲取結果集中單獨一列的所有值
$sth = $dbh -> prepare ( "SELECT name, colour FROM fruit" );
$sth -> execute ();
/* 獲取第一列所有值 */
$result = $sth -> fetchAll ( PDO :: FETCH_COLUMN , 0 );
var_dump ( $result );
~~~
~~~
Array(3)
(
[0] =>
string(5) => apple
[1] =>
string(4) => pear
[2] =>
string(10) => watermelon
)
~~~
~~~
;根據單獨的一列把所有值分組
$insert = $dbh -> prepare ( "INSERT INTO fruit(name, colour) VALUES (?, ?)" );
$insert -> execute (array( 'apple' , 'green' ));
$insert -> execute (array( 'pear' , 'yellow' ));
$sth = $dbh -> prepare ( "SELECT name, colour FROM fruit" );
$sth -> execute ();
/* 根據第一列分組 */
var_dump ( $sth -> fetchAll ( PDO :: FETCH_COLUMN | PDO :: FETCH_GROUP ));
~~~
輸出
~~~
array(3) {
["apple"]=>
array(2) {
[0]=>
string(5) "green"
[1]=>
string(3) "red"
}
["pear"]=>
array(2) {
[0]=>
string(5) "green"
[1]=>
string(6) "yellow"
}
["watermelon"]=>
array(1) {
[0]=>
string(5) "green"
}
}
~~~
~~~
;返回每行結果實例化為一個類
class fruit {
public $name ;
public $colour ;
}
$sth = $dbh -> prepare ( "SELECT name, colour FROM fruit" );
$sth -> execute ();
$result = $sth -> fetchAll ( PDO :: FETCH_CLASS , "fruit" );
var_dump ( $result );
~~~
輸出
~~~
array(3) {
[0]=>
object(fruit)#1 (2) {
["name"]=>
string(5) "apple"
["colour"]=>
string(5) "green"
}
[1]=>
object(fruit)#2 (2) {
["name"]=>
string(4) "pear"
["colour"]=>
string(6) "yellow"
}
[2]=>
object(fruit)#3 (2) {
["name"]=>
string(10) "watermelon"
["colour"]=>
string(4) "pink"
}
}
~~~
~~~
;每行調用一次函數
function fruit ( $name , $colour ) {
return " { $name } : { $colour } " ;
}
$sth = $dbh -> prepare ( "SELECT name, colour FROM fruit" );
$sth -> execute ();
$result = $sth -> fetchAll ( PDO :: FETCH_FUNC , "fruit" );
var_dump ( $result );
~~~
輸出
~~~
array(3) {
[0]=>
string(12) "apple: green"
[1]=>
string(12) "pear: yellow"
[2]=>
string(16) "watermelon: pink"
}
~~~
### 4-6 fetchColumn() 返回結果集中的下一行單獨的一列
~~~
string PDOStatement::fetchColumn ([ int $column_number = 0 ] )
~~~
> $column_number 從行里取回的列的索引數字。)。如果沒有提供值,則 PDOStatement::fetchColumn() 獲取第一列
> 從結果集中的下一行返回單獨的一列,如果沒有了,則返回 FALSE 。
~~~
;返回下一行的第一列
$sth = $dbh -> prepare ( "SELECT name, colour FROM fruit" );
$sth -> execute ();
/* 從結果集中的下一行獲取第一列 */
print( "從結果集中的下一行獲取第一列:\n" );
$result = $sth -> fetchColumn ();
print( "name = $result \n" );
print( "從結果集中的下一行獲取第二列:\n" );
$result = $sth -> fetchColumn ( 1 );
print( "colour = $result \n" );
~~~
輸出
~~~
從結果集中的下一行獲取第一列:
name = lemon
從結果集中的下一行獲取第二列:
colour = red
~~~
### 4-7 fetchObject() 將下一行作為一個對象返回
~~~
mixed PDOStatement::fetchObject ([ string $class_name = "stdClass" [, array $ctor_args ]] )
~~~
> $class_name 結果類的名稱
> $ctor_args 構造函數的參數
> 返回一個屬性名對應列表的類的實例
### 4-8 columnCount() 返回結果集的列數
~~~
int PDOStatement::columnCount ( void )
~~~
> 使用 PDOStatement::columnCount() 返回由 PDOStatement 對象代表的結果集中的列數。
> 如果是由 PDO::query() 返回的 PDOStatement 對象,則列數計算立即可用。
> 如果是由 PDO::prepare() 返回的 PDOStatement 對象,則在調用 PDOStatement::execute() 之前都不能準確地計算出列數。
~~~
;計算列數
$dbh = new PDO ( 'odbc:sample' , 'db2inst1' , 'ibmdb2' );
$sth = $dbh -> prepare ( "SELECT name, colour FROM fruit" );
/* 計算一個(不存在)的結果集中的列數 */
$colcount = $sth -> columnCount ();
print( "Before execute(), result set has $colcount columns (should be 0)\n" );
$sth -> execute ();
/* 計算結果集中的列數 */
$colcount = $sth -> columnCount ();
print( "After execute(), result set has $colcount columns (should be 2)\n" );
~~~
### 4-9 rowCount() 返回受SQL語句影響的行數
~~~
int PDOStatement::rowCount ( void )
~~~
> PDOStatement::rowCount() 返回上一個由對應的 PDOStatement 對象執行DELETE、 INSERT、或 UPDATE 語句受影響的行數。
> 如果上一條由相關 PDOStatement 執行的 SQL 語句是一條 SELECT 語句,有些數據可能返回由此語句返回的行數。但這種方式不能保證對所有數據有效,且對于可移植的應用不應依賴于此方式。
~~~
;返回刪除的行數
/* 從 FRUIT 數據表中刪除所有行 */
$del = $dbh -> prepare ( 'DELETE FROM fruit' );
$del -> execute ();
/* 返回被刪除的行數 */
print( "Return number of rows that were deleted:\n" );
$count = $del -> rowCount ();
~~~
輸出
~~~
Return number of rows that were deleted:
Deleted 9 rows.
~~~
~~~
;返回select語句返回的行數
$sql = "SELECT COUNT(*) FROM fruit WHERE calories > 100" ;
if ( $res = $conn -> query ( $sql )) {
/* 檢查符合 SELECT 語句的行數 */
if ( $res -> fetchColumn () > 0 ) {
/* 發出一條真正的 SELECT 語句并操作返回的結果 */
$sql = "SELECT name FROM fruit WHERE calories > 100" ;
foreach ( $conn -> query ( $sql ) as $row ) {
print "Name: " . $row [ 'NAME' ] . "\n" ;
}
}
/* 沒有匹配的行 -- 執行其他 */
else {
print "No rows matched the query." ;
}
}
$res = null ;
$conn = null ;
~~~
輸出
~~~
apple
banana
orange
pear
~~~
### 4-10 nextRowset() 在一個多行集語句句柄中推進到下一個行集
~~~
bool PDOStatement::nextRowset ( void )
~~~
> 一些數據庫服務支持返回一個以上行集(也被稱為結果集)的存儲過程。 PDOStatement::nextRowset() 使你能夠結合一個 PDOStatement 對象訪問第二個以及后續的行集。上述的每個行集可以有不同的列集合。
~~~
;獲取一個存儲過程返回的多個行集
$sql = 'CALL multiple_rowsets()' ;
$stmt = $conn -> query ( $sql );
$i = 1 ;
do {
$rowset = $stmt -> fetchAll ( PDO :: FETCH_NUM );
if ( $rowset ) {
printResultSet ( $rowset , $i );
}
$i ++;
} while ( $stmt -> nextRowset ());
function printResultSet (& $rowset , $i ) {
print "Result set $i :\n" ;
foreach ( $rowset as $row ) {
foreach ( $row as $col ) {
print $col . "\t" ;
}
print "\n" ;
}
print "\n" ;
}
~~~
輸出
~~~
Result set 1:
apple red
banana yellowResult set 2:
orange orange 150
banana yellow 175Result set 3:
lime green
apple red
banana yellow
~~~
### 4-11 getColumnMeta() 返回結果集中一列的元數據
~~~
array PDOStatement::getColumnMeta ( int $column )
~~~
### 4-12 關閉游標,語句可以再次被執行
~~~
bool PDOStatement::closeCursor ( void )
~~~
> PDOStatement::closeCursor() 釋放到數據庫服務的連接,以便發出其他 SQL 語句,但使語句處于一個可以被再次執行的狀態。
> PDOStatement::closeCursor() 要么是一個可選驅動的特有方法(效率最高)來實現,要么是在沒有驅動特定的功能時作為一般的PDO 備用來實現。一般的備用語義上與下面的 PHP 代碼相同:
~~~
do {
while ( $stmt -> fetch ())
;
if (! $stmt -> nextRowset ())
break;
} while ( true );
~~~
~~~
/* 創建一個 PDOStatement 對象 */
$stmt = $dbh -> prepare ( 'SELECT foo FROM bar' );
/* 創建第二個 PDOStatement 對象 */
$otherStmt = $dbh -> prepare ( 'SELECT foobaz FROM foobar' );
/* 執行第一條語句 */
$stmt -> execute ();
/* 從結果集中只取出第一行 */
$stmt -> fetch ();
/* The following call to closeCursor() may be required by some drivers */
$stmt -> closeCursor ();
/* 現在可以執行第二條語句了 */
$otherStmt -> execute ();
~~~
### 4-13 errorCode() 返回錯誤碼
~~~
string PDOStatement::errorCode ( void )
~~~
> 與 PDO::errorCode() 相同,只是 PDOStatement::errorCode() 只取回 PDOStatement 對象執行操作中的錯誤碼。
~~~
;獲取SQLSTATE錯誤碼
/* 引發一個錯誤 -- BONES 數據表不存在 */
$err = $dbh -> prepare ( 'SELECT skull FROM bones' );
$err -> execute ();
echo "\nPDOStatement::errorCode(): " ;
print $err -> errorCode ();
~~~
輸出
~~~
PDOStatement::errorCode(): 42S02
~~~
### 4-14 errorInfo() 返回錯誤信息
~~~
array PDOStatement::errorInfo ( void )
~~~
> PDOStatement::errorInfo() 返回一個關于上一次語句句柄執行操作的錯誤信息的數組 。該數組包含下列字段:
> 0 SQLSTATE 錯誤碼
1 具體驅動錯誤碼。
2 具體驅動錯誤信息。
~~~
/* 激發一個錯誤 -- BONES 數據表不存在 */
$sth = $dbh -> prepare ( 'SELECT skull FROM bones' );
$sth -> execute ();
echo "\nPDOStatement::errorInfo():\n" ;
$arr = $sth -> errorInfo ();
print_r ( $arr );
~~~
輸出
~~~
PDOStatement::errorInfo():
Array
(
[0] => 42S02
[1] => -204
[2] => [IBM][CLI Driver][DB2/LINUX] SQL0204N "DANIELS.BONES" is an undefined name. SQLSTATE=42704
)
~~~
### 4-15 setAttribute() 設置語句的屬性
~~~
bool PDOStatement::setAttribute ( int $attribute , mixed $value )
~~~
> 設置特定數據庫驅動語句的屬性
>> PDO::ATTR_CURSOR_NAME (Firebird 和 ODBC 特性): 為 UPDATE ... WHERE CURRENT OF 設置游標名稱。
### 4-16 getAttribute() 獲取語句的屬性
~~~
mixed PDOStatement::getAttribute ( int $attribute )
~~~
> 獲取特定數據庫驅動語句的屬性
>> PDO::ATTR_CURSOR_NAME (Firebird 和 ODBC 特性): 為 UPDATE ... WHERE CURRENT OF 設置游標名稱。
### 4-17 setFetchMode() 設置語句的獲取模式
~~~
bool PDOStatement::setFetchMode ( int $mode )
bool PDOStatement::setFetchMode ( int $PDO::FETCH_COLUMN , int $colno )
bool PDOStatement::setFetchMode ( int $PDO::FETCH_CLASS , string $classname , array $ctorargs )
bool PDOStatement::setFetchMode ( int $PDO::FETCH_INTO , object $object )
~~~
> $mode PDO::FETCH_*系列常量的一個
>> 1 PDO::FETCH_ASSOC:返回一個索引為結果集列名的數組
>> 2 PDO::FETCH_BOTH(默認):返回一個索引為結果集列名和以0開始的列號的數組
>> 3 PDO::FETCH_BOUND:返回 TRUE ,并分配結果集中的列值給 PDOStatement::bindColumn() 方法綁定的 PHP 變量。
>> 4 PDO::FETCH_CLASS:返回一個請求類的新實例,映射結果集中的列名到類中對應的屬性名。如果 fetch_style 包含 PDO::FETCH_CLASSTYPE(例如:PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE),則類名由第一列的值決定
>> 5 PDO::FETCH_INTO:更新一個被請求類已存在的實例,映射結果集中的列到類中命名的屬性
>> 6 PDO::FETCH_LAZY:結合使用 PDO::FETCH_BOTH 和 PDO::FETCH_OBJ,創建供用來訪問的對象變量名
>> 7 PDO::FETCH_NUM:返回一個索引為以0開始的結果集列號的數組
>> 8 PDO::FETCH_OBJ:返回一個屬性名對應結果集列名的匿名對象
> $colno 列號
> $classname 類名
> $ctorargs 構造函數參數
> $object 對象
~~~
;設置獲取模式
$sql = 'SELECT name, colour, calories FROM fruit' ;
try {
$stmt = $dbh -> query ( $sql );
$result = $stmt -> setFetchMode ( PDO :: FETCH_NUM );
while ( $row = $stmt -> fetch ()) {
print $row [ 0 ] . "\t" . $row [ 1 ] . "\t" . $row [ 2 ] . "\n" ;
}
}
catch ( PDOException $e ) {
print $e -> getMessage ();
}
~~~
輸出
~~~
apple red 150
banana yellow 250
orange orange 300
kiwi brown 75
lemon yellow 25
pear green 150
watermelon pink 90
~~~
###4-18 debugDumpParams() 打印SQL預處理命令
~~~
bool PDOStatement::debugDumpParams ( void )
~~~
> 直接打印出一條預處理語句包含的信息。提供正在使用的 SQL 查詢、所用參數(Params)的數目、參數的清單、參數名、用一個整數表示的參數類型(paramtype)、鍵名或位置、值、以及在查詢中的位置(如果當前 POD 驅動不支持,則為-1)。
> 此為一個用于調試的功能,在正常輸出的情況下直接輸出數據。
> 和直接將結果輸出到瀏覽器一樣,可使用輸出控制函數來捕獲當前函數的輸出,然后(例如)保存到一個 string 中。只打印此時此刻語句中的參數。額外的參數不存儲在語句中,也就不會被輸出。
~~~
/* 通過綁定 PHP 變量執行一條預處理語句 */
$calories = 150 ;
$colour = 'red' ;
$sth = $dbh -> prepare ( 'SELECT name, colour, calories
FROM fruit
WHERE calories < :calories AND colour = :colour' );
$sth -> bindParam ( ':calories' , $calories , PDO :: PARAM_INT );
$sth -> bindValue ( ':colour' , $colour , PDO :: PARAM_STR , 12 );
$sth -> execute ();
$sth -> debugDumpParams ();
~~~
輸出
~~~
SQL: [96] SELECT name, colour, calories
FROM fruit
WHERE calories < :calories AND colour = :colour
Params: 2
Key: Name: [9] :calories
paramno=-1
name=[9] ":calories"
is_param=1
param_type=1
Key: Name: [7] :colour
paramno=-1
name=[7] ":colour"
is_param=1
param_type=2
~~~
~~~
;使用未命名參數的例子
/* 通過綁定 PHP 變量執行一條預處理語句 */
$calories = 150 ;
$colour = 'red' ;
$name = 'apple' ;
$sth = $dbh -> prepare ( 'SELECT name, colour, calories
FROM fruit
WHERE calories < ? AND colour = ?' );
$sth -> bindParam ( 1 , $calories , PDO :: PARAM_INT );
$sth -> bindValue ( 2 , $colour , PDO :: PARAM_STR );
$sth -> execute ();
$sth -> debugDumpParams ();
~~~
輸出
~~~
SQL: [82] SELECT name, colour, calories
FROM fruit
WHERE calories < ? AND colour = ?
Params: 2
Key: Position #0:
paramno=0
name=[0] ""
is_param=1
param_type=1
Key: Position #1:
paramno=1
name=[0] ""
is_param=1
param_type=2
~~~
## 5 PDOException異常類
## 6 PDO常見驅動
- 更新記錄
- 概述
- 文件索引
- 函數索引
- 章節格式
- 框架流程
- 前:章節說明
- 主:(index.php)入口
- 主:(start.php)框架引導
- 主:(App.php)應用啟動
- 主:(App.php)應用調度
- C:(Controller.php)應用控制器
- M:(Model.php)數據模型
- V:(View.php)視圖對象
- 附:(App.php)應用啟動
- 附:(base.php)全局變量
- 附:(common.php)模式配置
- 附:(convention.php)全局配置
- 附:(Loader.php)自動加載器
- 附:(Build.php)自動生成
- 附:(Hook.php)監聽回調
- 附:(Route.php)全局路由
- 附:(Response.php)數據輸出
- 附:(Log.php)日志記錄
- 附:(Exception.php)異常處理
- 框架工具
- 另:(helper.php)輔助函數
- 另:(Cache.php)數據緩存
- 另:(Cookie.php)cookie操作
- 另:(Console.php)控制臺
- 另:(Debug.php)開發調試
- 另:(Error.php)錯誤處理
- 另:(Url.php)Url操作文件
- 另:(Loader.php)加載器實例化
- 另:(Input.php)數據輸入
- 另:(Lang.php)語言包管理
- 另:(ORM.php)ORM基類
- 另:(Process.php)進程管理
- 另:(Session.php)session操作
- 另:(Template.php)模板解析
- 框架驅動
- D:(\config)配置解析
- D:(\controller)控制器擴展
- D:(\model)模型擴展
- D:(\db)數據庫驅動
- D:(\view)模板解析
- D:(\template)模板標簽庫
- D:(\session)session驅動
- D:(\cache)緩存驅動
- D:(\console)控制臺
- D:(\process)進程擴展
- T:(\traits)Trait目錄
- D:(\exception)異常實現
- D:(\log)日志驅動
- 使用范例
- 服務器與框架的安裝
- 控制器操作
- 數據模型操作
- 視圖渲染控制
- MVC開發初探
- 模塊開發
- 入口文件定義全局變量
- 運行模式開發
- 框架配置
- 自動生成應用
- 事件與插件注冊
- 路由規則注冊
- 輸出控制
- 多種應用組織
- 綜合應用
- tp框架整合后臺auto架構快速開發
- 基礎原理
- php默認全局變量
- php的魔術方法
- php命名空間
- php的自動加載
- php的composer
- php的反射
- php的trait機制
- php設計模式
- php的系統時區
- php的異常錯誤
- php的輸出控制
- php的正則表達式
- php的閉包函數
- php的會話控制
- php的接口
- php的PDO
- php的字符串操作
- php的curl
- 框架心得
- 心:整體結構
- 心:配置詳解
- 心:加載器詳解
- 心:輸入輸出詳解
- 心:url路由詳解
- 心:模板詳解
- 心:模型詳解
- 心:日志詳解
- 心:緩存詳解
- 心:控制臺詳解
- 框架更新
- 4.20(驗證類,助手函數)
- 4.27(新模型Model功能)
- 5.4(新數據庫驅動)
- 7.28(自動加載)