PDO подготовил инструкции IN с указанными заполнителями не работает должным образом

Скажем, в сценарии: $ids = 2,3 . Но по какой-то причине записи возвращаются, как будто: $ids = 2 .

Я считаю, что в этой строке есть какая-то проблема из полного кода, потому что когда я возвращаю $ids , он возвращает 2,3 , но фактический запрос возвращается, как будто есть только один идентификатор. Т.е. он возвращает события только из одного курса (id 2).

 $statement->execute(array("ids" => $ids, 'timestart' => $timestart, 'timeend' => $timeend))) { 

мой полный код:

 $ids = array_map(function($item) { return $item->id; }, $entitlementsVOs); $ids = implode(', ', $ids); //echo shows 2,3 $timestart = isset($_GET['start']) && $_GET['start'] != "" ? $_GET['start'] : null; $timeend = isset($_GET['end']) && $_GET['end'] != "" ? $_GET['end'] : null; $statement = $this->connection->prepare("SELECT name AS title, timestart AS start, timestart + timeduration AS end FROM event WHERE courseid IN(:ids) AND timestart >= :timestart AND timestart + timeduration <= :timeend"); $statement->setFetchMode(\PDO::FETCH_CLASS, get_class(new EventVO())); if($statement->execute(array("ids" => $ids, 'timestart' => $timestart, 'timeend' => $timeend))) { return $statement->fetchAll(); } else { return null; } 

ps вручную запускает этот запрос в mysql workbench возвращает мои две записи (1 из идентификатора курса 2, а второй из курса 3), где я заменяю оператор (2,3), но при выполнении php я получаю только одну запись.

Если я жестко courseid IN(2,3) значения в php courseid IN(2,3) , например:

 $statement = $this->connection->prepare("SELECT name AS title, timestart AS start, timestart + timeduration AS end FROM event WHERE courseid IN(2,3) AND timestart >= :timestart AND timestart + timeduration <= :timeend"); 

Я получаю то, что ожидаю, поэтому я считаю, что есть некоторая проблема с implode , или с оператором IN или с помощью $statement->execute .

Редактировать:

Я прочитал обман, но я не знаю, с чего начать с названных заполнителей, чтобы добиться того же. Мой вопрос в том, что, когда у меня есть оба параметра и оператор IN, обманщик использует оператор IN только с позиционерами позиции.

Изменить 2

Я прочитал второй обман, это не связано, в моем вопросе используется сочетание как IN, так и названных заполнителей, связанный вопрос не затрагивает это, однако у меня есть решение теперь в ответе.

Solutions Collecting From Web of "PDO подготовил инструкции IN с указанными заполнителями не работает должным образом"

Это должно сработать для вас:

Так, как уже сказано в комментариях, вам нужно заполнить место для каждого значения, которое вы хотите привязать к предложению IN.

Здесь я создаю сначала массив $ids который содержит только простые идентификаторы, например

 [2, 3] 

Затем я также создал массив $preparedIds который содержит заполнители в виде массива, который затем вы затем используете в подготовленном операторе. Этот массив выглядит примерно так:

 [":id2", ":id3"] 

И я также создаю массив под названием $preparedValues который содержит $preparedIds качестве ключей и $ids как значения, которые позже вы можете использовать для вызова execute() . Массив выглядит примерно так:

 [":id2" => 2, ":id3" => 3] 

После этого вы хорошо пойдете. В подготовленном заявлении я просто implode() массив $preparedIds prepareIds, так что оператор SQL выглядит примерно так:

 ... IN(:id2,:id3) ... 

А затем вы можете просто execute() ваш запрос. Там я просто array_merge() ваш массив $preparedValues array_merge() с другим массивом заполнителей.

 <?php $ids = array_map(function($item){ return $item->id; }, $entitlementsVOs); $preparedIds = array_map(function($v){ return ":id$v"; }, $ids); $preparedValues = array_combine($preparedIds, $ids); $timestart = (!empty($_GET['start']) ? $_GET['start'] : NULL ); $timeend = (!empty($_GET['end']) ? $_GET['end'] : NULL ); $statement = $this->connection->prepare("SELECT name AS title, timestart AS start, timestart + timeduration AS end FROM event WHERE courseid IN(" . implode(",", $preparedIds) . ") AND timestart >= :timestart AND timestart + timeduration <= :timeend"); $statement->setFetchMode(\PDO::FETCH_CLASS, get_class(new EventVO())); if($statement->execute(array_merge($preparedValues, ["timestart" => $timestart, "timeend" => $timeend]))) { return $statement->fetchAll(); } else { return null; } ?> 

Также я думаю, что вы хотите поместить запрос if из вашего запроса, так как ваш запрос не будет выполняться, если значения $timestart и $timeend равны NULL.