1. 程式人生 > 其它 >PHP開發過程的那些坑(四) ——PDO bindParam函式

PHP開發過程的那些坑(四) ——PDO bindParam函式

PHP開發過程的那些坑(四)——PDO bindParam函式

(原創內容,轉載請註明來源,謝謝)

坑:

bindParam是PDOStatement的一個方法,用於在PDO操作中繫結佔位符的內容,進行替換,是PDO安全性的一大保障。

通常用法如下:(摘自PHP官方文件)

<?php
/* 通過繫結的 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();
?>

可以看到,通過bindParam方法,可以把calories和colour替換成上面的變數。這個對防止sql注入具有重要作用。

但是,最近我遇到的問題是,通常繫結的內容很多個,可以用foreach來實現,我也就寫了一個方法,如下:

//繫結sql(錯誤的方式)
private functionbindSql($query, $arrData){
//注:arrData=array(col1=>val1,col2=>val2…)
         if(empty($arrData)){
                  returnnull;
         }else{
                  foreach($arrDataas $col => $val){
                            $col= ':'.$col;
                            $query->bindParam($col, $val);
                  }
                  return$query;
         }                          
}

但是,當我呼叫這個方法時,發現如果arrData只有一個引數時,正常執行,但是當傳入兩個或者以上時,就出問題了,最後繫結的內容全部變成最後一個val了。

經過我多次和原例子比對,發現沒有問題,百思不得其解,只能再次看官方文件,直到我看到了這個人的留言:(摘自PHP官方文件)

瞬間恍然大悟。需要在$val前面加一個取地址符號&。

分析:

再次認真檢視官方文件,發現其對bindParam的定義如下:(摘自官方文件)

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

注意檢視第二個引數 mixed &$variable,發現有個取地址符號。即此引數是引用繫結,在最終執行sql時才會真正被取值。

因此,單條的使用bindParam(包括連續好幾行都是這個,類似官方文件)可以不用取地址符號,因為每次用不同的變數,則取不同的地址。而如果用foreach時,必須使用&符號,否則隨著foreach的迭代,會被取到最後一個內容當作結果。

改進措施:

加上取地址符即可。

//繫結sql(正確的方式)
private functionbindSql($query, $arrData){
//注:arrData=array(col1=>val1,col2=>val2…)
         if(empty($arrData)){
                  returnnull;
         }else{
                  foreach($arrDataas $col => &$val){
                            $col= ':'.$col;
                            $query->bindParam($col, $val);
                  }
                  return$query;
         }                          
}

——written by linhxx 2017.07.25

相關閱讀:

PHP開發過程的那些坑(三) ——PHParray_shift函式

PHP開發過程的那些坑(二) ——PHP empty函式

PHP開發過程的那些坑(一) ——物件拷貝