在PDOStatement 類中兩種方法的具體說明如下
bool PDOStatement::bindParam ( mixed $parameter , mixed &$variable [, int $data_type = PDO::PARAM_STR [, int $length [, mixed $driver_options ]]] )bool PDOStatement::bindValue ( mixed $parameter , mixed $value [, int $data_type = PDO::PARAM_STR ] )
區別1:bindParam是綁定一個參數到指定的變數名,bindValue則是把一個值綁定到一個參數
$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,都能夠正常執行,但是如果換成如下代碼$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);bindParam就會報如下錯誤,但是bindValue卻可以正常執行
Fatal error: Cannot pass parameter 2 by reference
總結: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 = ?');$id = 1;$st->bindParam(1,$id,PDO::PARAM_INT);$id = 2;$st->execute();$rs = $st->fetchAll();print_r($rs);首先給$id賦值為1,bindParam綁定變數,在execute前,更改$id為2,然後進行執行操作,此時獲得的結果集是當id=2的時候的查詢結果,並非是id為1時的查詢結果,這就是變數作為引用的解釋,在execute之前,我們可以對此變數進行替換,而執行execute操作時候代入的變數值,是該變數最後一次更改的值。$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);
而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('insert into tabletest(id,name) values(?,?)');$params = array(1,'張三');foreach($params as $k => $v){ $index = $k + 1; $st->bindParam($index,$v);}$st->execute();正常情況被執行的sql語句應該是insert into tabletest(id,name) values(1,'張三');
其實真正執行的sql語句卻是insert into tabletest(id,name) values('男','男');
究其原因就是bindParam中的變數作為了引用被綁定,因此最後每個欄位插入的數值都變成了最後一個欄位的值,而此時我們使用bindValue就不會出現這種問題了。此例中還有一點需要說明的是如果使用的是問號預留位置和索引數組結合,特別需要注意bindValue的參數標識符(該方法的第一個參數),索引數組預設從0開始,而bindValue的參數標識符是以1開始,如果直接套入索引數組的0下標,那麼程式就會報錯,使用的時候一定需要注意。
以上就介紹了php pdo中PDOStatement 類的bindParam和bindValue方法的區別,包括了方面的內容,希望對PHP教程有興趣的朋友有所協助。