Как связать параметры массива в Yii Framework? - PullRequest
9 голосов
/ 02 марта 2012

У меня есть код ниже:

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

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

Но результат запроса неверен. Как связать параметры для такого IN условия?

Ответы [ 4 ]

7 голосов
/ 02 марта 2012

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

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

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

6 голосов
/ 28 марта 2014

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

ОБНОВЛЕНИЕ

На самом деле, в Yii есть гораздо более понятный способ сделать это:*

См. Документы

1 голос
/ 30 ноября 2013

Использование цепочки методов Yii в CDbCommand для построения вашего запроса (как в ответе Удая Саванта), как правило, является хорошим выбором.Если необходимость создания фрагмента запроса не является идеальной, хорошей альтернативой является выравнивание массива параметров, чтобы не обойти защиту от 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.

0 голосов
/ 21 мая 2019

В Yii есть два метода:

  1. bindValue(), используемый в упомянутом вопросе
  2. bindValues($paramsArray) require т.е. $paramsArray = array(':index'=>$value)

IЯ использую следующий код, который работает для меня отлично:

$query = "UPDATE viewing_request SET  ViewingApiResponse=:ViewingApiResponse ,ViewingApiData = :ViewingApiData  WHERE id='{$id}'";

$executArray = array(
  ':ViewingApiResponse'=>$data['ViewingApiResponse'],  
  ':ViewingApiData'=>$data['ViewingApiData']  
);
$result = Yii::$app->db->createCommand($query)
    ->bindValues($executArray)
    ->execute();
...