2015-04-30 3 views
2

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

Я верю, что в этой строке есть какая-то проблема из полного кода, потому что когда я эхо $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; 
} 

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

Если я жесткий код значения в 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.

Edit:

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

Edit 2

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

+0

Вам нужно столько заполнителей, сколько хотите привязать значения в своем разделе IN! – Rizier123

+2

Ваши '$ ids' передаются в MySQL как строка и не преобразуются в массив MySQL. Эффективно вы говорите MySQL, чтобы сделать это: 'courseid IN ('2,3')', который является всего лишь одним значением, в отличие от желаемого 'courseid IN (2,3)' – MonkeyZeus

+0

@MonkeyZeus спасибо за помощь, можете ли вы помогите с ответом при использовании '$ ids' – user2727195

ответ

1

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

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

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

[2, 3] 

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

[":id2", ":id3"] 

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

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

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

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

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

<?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; 
    } 

?> 

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