Intereting Posts
Подписки WooCommerce – получение связанных заказов Идентификаторы для определенной подписки Ошибка php preg_split при переключении с split на preg_split Ошибка PHP – не может переопределять функцию Когда лучше проверить асинхронные запросы cURL для завершения? CodeIgniter Загрузка больших файлов Как использовать WHERE IN с Doctrine 2 Получение сведений с одной динамической страницы на другую – повторная публикация Строгие стандарты: только переменные должны передаваться по ссылке в wordpress / wp-includes / class-oembed.php в строке 116 PHP – содержимое массива lookup с синтаксисом точки Как разрешить удаленный доступ к моему WAMP-серверу для мобильных устройств (Android) Magento getUrl не работает с объектом каталога / категории? Вложенные ресурсы MySQL (сводные таблицы) для просмотра / обновления / управления MySQL в запрошенной связанной библиотеке openssl установлена ​​неправильная версия Цепочки выбираются в jQuery: несколько запросов AJAX Ошибка PHP PDO при использовании заполнителей в предложении LIMIT запроса MySQL

PDO связывает n раз такое же значение с foreach

У меня есть функция в PHP, которая должна связывать в MySQL IN так много переменных, которые находятся в массиве. Моя проблема в том, что переменная и ключ меняются, но функция связывает только последнее значение n раз.

У меня нет идеи, где проблема …

Вот мой метод класса:

public function getOtListByOtNumbers($conditions){ $data_array = $conditions[SEARCH_OT]; # To find last key (remove coma) $quantity = count($data_array); $marks = ''; # Bind name string && rewriting value as integer foreach ($data_array as $key => $value){ $i = $key+1; if ($i == $quantity){ $marks .= ':key'.$i; } else { $marks .= ':key'.$i.', '; } } # Query $sql=" SELECT c_int_id, c_ot, c_tickets_amount, c_basket_value, c_person, c_company, c_city, c_package_number, c_delivery_method, c_ot_date, c_email, c_phone, c_comment, c_send FROM ws_orders WHERE c_ot IN (".$marks.") ORDER BY c_int_id DESC LIMIT :first, :last "; $stmt = $this->PDO->prepare($sql); # Bind n values // Here is a problem var_dump($data_array); // var dump 1 foreach ($data_array as $key => $param){ $key_number = $key +1; $key_name = 'key'.$key_number; $stmt->bindParam($key_name, $param, PDO::PARAM_INT); var_dump($key_name); // var dump 2 var_dump($param); // var dump 3 } # Bind limit values $stmt->bindParam('first', $conditions[OT_SEARCH_FIRST_ROW], PDO::PARAM_INT); $stmt->bindParam('last', $conditions[OT_SEARCH_ROW_LIMIT], PDO::PARAM_INT); # If executed return result if ($stmt->execute() != FALSE) { $stmt_result = $stmt->fetchAll(); $stmt->closeCursor(); var_dump($stmt_result); // var dump 4 # If not executed print debug and return FALSE } else { var_dump($stmt->errorInfo()); $this->debugQuery($stmt); $stmt_result = FALSE; } return $stmt_result; } 

Вот var dupms:

var dump 1

 array (size=2) 0 => string '2761531' 1 => string '2760650' 

var dump 2 & 3

 string 'key1' (length=4) string '2761531' string 'key2' (length=4) string '2760650' 

SQL-запрос из этого выполнения

  SELECT c_int_id, c_ot, c_tickets_amount, c_basket_value, c_person, c_company, c_city, c_package_number, c_delivery_method, c_ot_date, c_email, c_phone, c_comment, c_send FROM ws_orders WHERE c_ot IN ('2760650', '2760650') ORDER BY c_int_id DESC LIMIT 0, 30 

Так что я делаю неправильно?

РЕДАКТИРОВАТЬ




Так что я сделал это;) Проблема была в foreach

Вместо:

  foreach ($data_array as $key => $param){ $key_number = $key +1; $key_name = 'key'.$key_number; $stmt->bindParam($key_name, $param, PDO::PARAM_INT); var_dump($key_name); // var dump 2 var_dump($param); // var dump 3 } 

Я даю:

  for ($key_number = 0; $key_number < $quantity + 1; $key_number++) { $key_name = 'key'.$key_number; $stmt->bindParam($key_name, $data_array[$key_number], PDO::PARAM_INT); } 

И это работает, но я до сих пор не знаю, в чем проблема с предыдущим foreach …

Существует различие между PDO::bindParam() и PDO::bindValue() . PDO::bindParam связывает ссылку , а не значение. Когда процесс foreach завершается, $param будет ссылаться на последнее значение массива. Во время execute вызова все привязанные ссылки будут оцениваться с одинаковым значением.

Официальная документация PDO::bindParam гласит:

В отличие от PDOStatement :: bindValue () переменная привязана как ссылка и будет оцениваться только в момент вызова PDOStatement :: execute ().

Если вы хотите, чтобы значения привязки в foreach использовали PDO::bindValue .

Если вы передадите переменную в качестве ссылки, она будет работать нормально для значения, но не будет работать для ключа.

Пример:

 foreach ($data_array as $key => &$param) { $key_number = $key + 1; //this won't work $key_name = 'key' . $key_number; $stmt->bindParam($key_name, $param, PDO::PARAM_INT); var_dump($key_name); // var dump 2 var_dump($param); // var dump 3 } 

Проблема в том, что BindParam передает второе значение по ссылке. PHP повторно использует (или появляется в этом случае) адрес $ param, а не фактическое значение. Ваш foreach мог бы использовать:

 $stmt->bindParam($key, $data_array[$key]); 

Это приводит к привязке адресного адреса массива к этому месту ключа, поэтому, когда ваш sql выполняется, он получает правильное значение.

Вы, наверное, хотели:

 $stmt->bindValue($key, $param); 

который должен оцениваться в цикле foreach вместо инструкции execute и является переданным значением вместо адреса.