php pdo中PDOStatement 類別的bindParam和bindValue方法的區別

WBOY
發布: 2016-08-08 09:25:24
原創
1213 人瀏覽過

在PDOStatement 類別中兩種方法的具體說明如下

bool PDOStatement::bindParam ( mixed $parameter , mixed &$variable [, int $data_type = PDO::PARAM_STR [, int $length [, mixed $driver_options ]]] )<pre name="code" class="php">bool PDOStatement::bindValue ( mixed $parameter , mixed $value [, int $data_type = PDO::PARAM_STR ] )
登入後複製
登入後複製
登入後複製

區別1:bindParam是綁定一個參數到指定的變數名,bindValue則是把一個值綁定到一個參數

中,不管是bindParam或bindValue,都能夠正常執行,但是如果換成如下程式碼
<pre name="code" class="php">$db = new PDO('mysql:host=localhost;dbname=dbtest;charset=utf8','user','pass');
$st = $db->prepare('select * from tabletest where id = ?');
$id = 1;
$st->bindParam(1,$id,PDO::PARAM_INT);
//$st->bindValue(1,$id,PDO::PARAM_INT);
登入後複製

bindParam就會報如下錯誤,但是bindValue卻可以正常執行

登入後複製
登入後複製
總結:bindParam第二個參數有且只能是一個變數名, 不能是一個具體的值,bindValue既可以綁定一個變數名,又可以綁定一個值

區別2:不同於PDOStatement::bindValue(),PDOStatement::bindParam()中的變數作為參考被綁定,並且只在PDOStatement::execute() 被呼叫的時候才取其值

$db = new PDO('mysql:host=localhost;dbname=dbtest;charset=utf8','user','pass');
$st = $db->prepare('select * from tabletest where id = ?');
$st->bindParam(1,1,PDO::PARAM_INT);
//$st->bindValue(1,1,PDO::PARAM_INT);
登入後複製
首先給$id賦值為1,bindParam綁定變量,在execute前,更改$id為2,然後進行執行操作,此時獲得的結果集是當id=2的時候的查詢結果,並非是id為1時的查詢結果,這就是變數作為引用的解釋,在execute之前,我們可以對此變數進行替換,而執行execute操作時候代入的變數值,是該變數最後一次改變的值。

Fatal error: Cannot pass parameter 2 by reference
登入後複製

而bindValue則不同,在使用bindValue綁定變數後,即使在執行execute之前改變了該變數的值,那麼結果也不會改變。例如上例即使我們把$id改為了2,但是最後執行的結果仍然會輸出$id =1時候的結果,因為bindValue綁定的並非是變數的引用,不會隨著變數的改變而改變。

雖然兩者都能完成sql參數的綁定,但是兩者仍然有區別,在實際應用中,我們應該選擇適合我們的,下面舉一個bindParam使用不當的例子

假設有一個數據表有整形id和字串型name兩個字段,有一數組資料$params = array(1,'張三')準備使用預處理進行插入,具體程式碼如下

$db = new PDO('mysql:host=localhost;dbname=dbtest;charset=utf8','user','pass');
$st = $db->prepare('select * from tabletest where id = ?');
$id = 1;
$st->bindParam(1,$id,PDO::PARAM_INT);
$id = 2;
$st->execute();
$rs = $st->fetchAll();
print_r($rs);
登入後複製
正常情況被執行的sql語句應該是

$db = new PDO('mysql:host=localhost;dbname=dbtest;charset=utf8','user','pass');
$st = $db->prepare('select * from tabletest where id = ?');
$id = 1;
$st->bindValue(1,$id,PDO::PARAM_INT);
$id = 2;
$st->execute();
$rs = $st->fetchAll();
print_r($rs);
登入後複製
其實真正執行的sql語句卻是

$db = new PDO('mysql:host=localhost;dbname=dbtest;charset=utf8','user','pass');
$st = $db->prepare('insert into tabletest(id,name) values(?,?)');
$params = array(1,'张三');
foreach($params as $k => $v){
    $index = $k + 1;
    $st->bindParam($index,$v);
}
$st->execute();
登入後複製

究其原因就是bindParam中的變數作為了引用被綁定,因此最後每個欄位插入的數值都變成了最後一個欄位的值,而此時我們使用bindValue就不會有這種問題了。此例中還有一點需要說明的是如果使用的是問號佔位符和索引數組結合,特別需要注意bindValue的參數標識符(該方法的第一個參數),索引數組預設從0開始,而bindValue的參數標識符是以1開始,如果直接套入索引數組的0下標,那麼程式就會報錯,使用的時候一定要注意。

以上就介紹了php pdo中PDOStatement 類別的bindParam和bindValue方法的差別,包含了面向的內容,希望對PHP教學有興趣的朋友有幫助。

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板