Как связать параметры массива в структуре YII?

У меня есть пример php:

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

Я использовал yii для обеспечения функции db:

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

но результат запроса корректен, поэтому, если это так, как я могу это сделать?

3 ответа

теперь используйте его так:

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

Я попытаюсь вернуться с помощью метода $command->bindValue().


Несколько раз сталкиваясь с этой проблемой в моих проектах, я придумал следующий рабочий процесс 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();

Смотрите Документы


Использование цепочки методов Yii в CDbCommand для построения вашего запроса (как и в ответе 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.

licensed under cc by-sa 3.0 with attribution.