PDO PHP bindValue не работает

Я знаю, что это было задано 1000 раз, но по какой-то причине я продолжаю ударять головой по стене.

Это работает:

$sql = 'SELECT a.eventCode, a.eventTime, a.teamCode, a.playerCode, b.lastName, b.firstName, b.number, a.xCoord, a.yCoord, a.id '; $sql = $sql . 'FROM events a, players b '; $sql = $sql . 'WHERE a.regGUID in ( ' . $regGUID . ' ) and '; $sql = $sql . 'a.playerCode=b.playerCode and a.gameCode = "' . $game . '" order by a.eventTime desc, a.actionCode asc'; $stmt = $db->prepare($sql); $results = $stmt->execute(); 

Это не означает:

 $sql = 'SELECT a.eventCode, a.eventTime, a.teamCode, a.playerCode, b.lastName, b.firstName, b.number, a.xCoord, a.yCoord, a.id '; $sql = $sql . 'FROM events a, players b '; $sql = $sql . 'WHERE a.regGUID in ( :regGUID ) and '; $sql = $sql . 'a.playerCode=b.playerCode and a.gameCode = :game order by a.eventTime desc, a.actionCode asc'; $stmt = $db->prepare($sql); $stmt->bindValue(':regGUID', $regGUID, PDO::PARAM_STR); $stmt->bindValue(':game', $game, PDO::PARAM_STR); $results = $stmt->execute(); 

Что мне не хватает? благодаря

Solutions Collecting From Web of "PDO PHP bindValue не работает"

Проблема здесь:

 $sql = $sql . 'WHERE a.regGUID in ( :regGUID ) and '; $stmt->bindValue(':regGUID', $regGUID, PDO::PARAM_STR); 

Я предполагаю, что $ regGUID является разделенным запятыми списком цитируемых строк.

Каждый параметр запроса принимает только одно скалярное значение. Не списки значений.

Таким образом, у вас есть два варианта:

  1. Продолжайте интерполировать строку $ regGUID, даже если вы используете параметры для других скалярных значений. Но вы все же хотите быть осторожным, чтобы избежать инъекции SQL, поэтому вы должны правильно сформировать строку $ regGUID. Вы не можете просто вызвать PDO :: quote () для всей строки, что сделало бы ее одной кавычкой, содержащей UUID и запятые. Вы должны убедиться, что каждая строка UUID экранирована и цитируется отдельно, затем объедините список вместе и проинтегрируйте его в предложение IN.

     $regGUIDs = explode(',', $regGUID); $regGUIDs = array_map(function ($g) { return $db->quote($g); }, $regGUIDs); $regGUID = implode(',', $regGUIDs); $sql = $sql . 'WHERE a.regGUID in (' . $regGUID . ') and '; 
  2. explode explode() $ regGUID в массив и добавить один параметр запроса для каждого элемента массива. Интерполируйте динамический список заполнителей параметров запроса.

     $regGUIDs = explode(',', $regGUID); $params = array_fill(1, count($regGUIDs), '?'); $sql = $sql . ' WHERE a.regGUID in ( ' . implode(',', $params) . ' ) and '; 

Вы можете связатьValue () в цикле для массива, но имейте в виду, что другие параметры также должны быть связаны положением, а не по имени. У PDO есть ошибки, которые делают его недовольным, когда вы пытаетесь смешивать два разных стиля параметров в одном запросе.

Вместо использования bindValue () я просто передаю массив значений параметров в PDOStatement :: execute (), что намного проще.

 $paramValues = $regGUIDs; $paramValues[] = $game; $results = $stmt->execute($paramValues); 

Это действительно спрашивали 1000 раз.

Подготовленные операторы могут принимать только скалярные значения , а не произвольные части SQL-запроса.

Вы должны сформировать инструкцию IN (), используя столько заполнителей, как и многие элементы, которые вы должны вставить, а затем привязать их один за другим.

Для облегчения этой задачи можно использовать некоторую вспомогательную функцию.

Скажем, используя библиотеку SafeMysql, этот код можно записать как

 $sql = 'SELECT * FROM events a, players b WHERE regGUID in (?a) and'; $sql .= ' a.playerCode=b.playerCode and a.gameCode = ?s'; $sql .= ' order by a.eventTime desc, a.actionCode asc'; $results = $db->getAll($sql,$regGUID,$game); 

Обратите внимание, что $regGUID должен быть массивом, а не строкой, а $results уже содержит все запрошенные данные без дальнейшей обработки.

Каково содержание $regGUID ? Поскольку вы используете предложение in , я подозреваю, что список, разделенный запятыми.

Привязка переменной к параметру не похожа на замену этой строки на запрос; это как сказать MySQL, как использовать ваши фактические переменные PHP. Поэтому, если вы привязываете строку к параметру запроса '1,2,3' , она остается одной строкой и не переинтерпретируется как список чисел.

Следовательно, если $regGUID – это что-то вроде "'AAA1', 'BBB2'" , ваш первый запрос становится

 ... WHERE a.regGUID in ( 'AAA1', 'BBB2' ) ... 

но ваш второй запрос больше похож на

 ... WHERE a.regGUID in ( '\'AAA1\', \'BBB2\'' ) ... 

это то же самое, что сказать

 ... WHERE a.regGUID = '\'AAA1\', \'BBB2\'' ... 

Как и другие, вы можете привязать только одно скалярное значение к заполнителю. Таким образом, это означает, что вам действительно нужен заполнитель для каждого значения в инструкции IN . Обычно я делаю что-то вроде следующего. Следует отметить, что я никогда не использую bindValue поэтому, если у него есть правила о том, что вещи должны быть ссылками, такими как Mysqli, тогда может потребоваться изменить следующее:

 $regGUIDPlaceholders = array(); // prepare the placeholders // assume regGUID is an array - if its a string then explode on whatever to make it an array foreach($regGUID as $k => $v) { $placeholder = ':regGUID' . $k; $regGUIDPlaceholders[$key] = $value; } // prepare the IN statememnt $in = sprintf('IN (%s)', implode(',', array_keys($regGUIDPlaceholders))); $sql = 'SELECT a.eventCode, a.eventTime, a.teamCode, a.playerCode, b.lastName, b.firstName, b.number, a.xCoord, a.yCoord, a.id '; $sql = $sql . 'FROM events a, players b '; // USE the IN statement dynamically prepared above $sql = $sql . 'WHERE a.regGUID '. $in . ' and '; $sql = $sql . 'a.playerCode=b.playerCode and a.gameCode = :game order by a.eventTime desc, a.actionCode asc'; $stmt = $db->prepare($sql); // bind each GUID to its placeholder foreach($regGUIDPlaceholders as $placeholder => $value) { $stmt->bindValue($placeholder, $value, PDO::PARAM_STR); } $stmt->bindValue(':game', $game, PDO::PARAM_STR); $results = $stmt->execute();