2012-03-02 24 views
8

下面我有PHP的情況下:如何在YII框架中綁定數組參數?

$inputs = "1,2,3,4,5"; 
$sql = "SELECT * FROM obj WHERE id IN(:input)"; 

我用警予提供DB函數:

$commond = Yii::app()->db->createCommand($sql); 
$commond->bindValue(":input", $inputs , PDO::PARAM_STR); 

但查詢結果的,正確的,因此,如果這我該怎麼辦?

+2

Uday Sawant的回答是一個很好的解決方法。上面的代碼實際上會導致這條SQL語句:'SELECT * FROM obj WHERE id IN('1,2,3,4,5')'。請注意'$ inputs'的值是一個**單個字符串**。這就是結果不正確的原因。如果你真的必須使用'bindValue',你必須從像[this here]這樣的數組構建SQL(http://stackoverflow.com/questions/6071619/pdo-bind-unknown-number-of-parameters)。 – Shiki 2012-03-02 13:24:06

回答

7

現在這樣使用它

$command = Yii::app()->db->createCommand() 
    ->select() 
    ->from('tableName') 
    ->where(array('in', 'id', explode(',', $inputs))); 

我會盡力找回與$command->bindValue()方法。

+0

謝謝支持! – Cherry 2012-03-02 07:59:40

1

在CDbCommand中使用Yii的方法鏈接來構建查詢(如Uday Sawant的答案)通常是一個不錯的選擇。如果有零碎構造查詢不理想,一個好的辦法是讓你不繞過SQL注入防護,像這樣扁平化您的參數數組:

$sql = "SELECT * FROM obj WHERE id IN (:id_array) AND other_field = :other_value"; 
$args = array(
    'id_array' => array(1, 2, 3, 4, 5), 
    'other_value' => 12, 
); 

// Flatten array arguments into multiple parameters, 
// replacing with parameter lists in the SQL 
$newArgs = array(); 
$replace = array(); 
foreach($args as $oldKey => $input) { 
    if(!is_array($input)) { 
    $newArgs[$oldKey] = $args[$oldKey]; 
    continue; 
    } 

    $replace[':'.$oldKey] = array(); 
    foreach($input as $i => $value) { 
    $replace[':'.$oldKey][] = ':'.$oldKey.$i; 
    $newArgs[$oldKey.$i] = $value; 
    } 
    $replace[':'.$oldKey] = implode(', ', $replace[':'.$oldKey]); 
} 
$sql = strtr($sql, $replace); 

$query = Yii::app()->db->createCommand($sql); 
$query->params = $newArgs; 
$query->queryAll(); 

在這個例子中,最終的SQL和參數分別是:

SELECT * FROM obj WHERE id IN (:id_array0, :id_array1, :id_array2, :id_array3, :id_array4) AND other_field = :other_value 
array(
    'id_array0' => 1, 
    'id_array1' => 2, 
    'id_array2' => 3, 
    'id_array3' => 4, 
    'id_array4' => 5, 
    'other_value' => 12, 
) 

在使用原始的SQL語句,如果項目是首選標準,最大的好處是你可以捆綁這件事作爲一個效用函數和重用它的任何查詢。這是一種恥辱Yii不會以這種方式自動擴展數組參數,但您也可以將此支持自己添加到直接使用PDO的項目中。

6

在我的項目中遇到過這個問題幾次後,我用以下Yii解決方法使用CDbCriteria,這有點難以理解,但卻提供了參數計數匹配的安全性。

當適用於您的例子我的代碼是:

$inputs = array(1,2,3,4,5); 
$criteria = new CDbCriteria(); 
$criteria->addInCondition('id',$inputs); 

$sql = 'SELECT * FROM obj WHERE '.$criteria->condition; 
$command = Yii::app()->db->createCommand($sql); 
$results = $command->queryAll(true, $criteria->params); 

UPDATE

其實是有做這個內置的Yii更清潔的方式:

$results = Yii::app()->db->createCommand() 
    ->select() 
    ->from('obj') 
    ->where(['in', 'id', $inputs]) 
    ->queryAll(); 

Docs