PDO, смешивающий неназванные и именованные параметры - PullRequest
4 голосов
/ 12 марта 2012

Я пытаюсь использовать это для базового поиска с нумерацией страниц:

$construct = '? AND ? AND..';

$query = $database->prepare('SELECT * FROM something WHERE something LIKE ' . $construct . ' LIMIT :offset, :results');

Единственная причина, по которой я их смешиваю, заключается в том, что неназванные параметры не могут иметь значения int из-за ошибки в PHP: https://bugs.php.net/bug.php?id=44639

Однако, если я не смешиваю их, как я могу искать переменное количество терминов, используя привязки?

Обновление

После того, как я возился с этим, я решил более или менее, используя именованные параметры и некоторые циклы:

    // build prepared statement
    $construct = '';
    for ($x = 0; $x <= $searchArrayCount; $x++) {
        $construct .= ($x < $searchArrayCount)
                    ? ":var$x OR name LIKE "
                    : ":var$x LIMIT :start, :perPage";
    }

    $query = $database->prepare('SELECT something FROM something WHERE name LIKE ' . $construct);

    // bind parameters
    for ($x = 0; $x <= $searchArrayCount; $x++) {
        $searchArray[$x] = "%$searchArray[$x]%";
        $query->bindParam(":var$x", $searchArray[$x]);
    }

    $query->bindParam(':start', $searchArrayCount, PDO::PARAM_INT);
    $query->bindParam(':perPage', $perPage, PDO::PARAM_INT);

Если есть более оптимальный способ сделать это, я бы хотел, чтобы об этом сообщили.

Ответы [ 2 ]

1 голос
/ 14 мая 2012

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

Может быть проблема с типом данных переменных.Рекомендуется использовать функцию intval() раньше.

Ваше решение с неназванным типом данных может выглядеть следующим образом:

$counter = 0;

//build prepared statement

$query = $database->prepare('SELECT something FROM something WHERE 0 OR '.
implode(' OR ', array_fill(0 , $searchArrayCount, 'name LIKE ?')).
        ' LIMIT ?, ?');

// bind parameters
foreach($searchArray as $value)
{
    $counter++;
    $query->bindValue($counter, ('%'.$value.'%'), PDO::PARAM_STR);
}

$query->bindValue(($counter+1), ($page*$perPage), PDO::PARAM_INT);
$query->bindParam(($counter+2), $perPage, PDO::PARAM_INT);

Примечание. Я использовал bindValue() до bindParam().И будьте осторожны с первым параметром LIMIT.Если счет будет здесь, то выбор будет начинаться с конца данных, и строки не будут возвращены.

0 голосов
/ 12 марта 2012

Столкнулся с подобной проблемой, в конце я просто пропустил параметры связывания в предложении LIMIT:

sprintf('LIMIT %d, %d', $offset, $size);

Другой обходной путь (если ваша система поддерживает это) - переключиться на привязку собственных параметров. Очевидно, именно этот слой эмуляции демонстрирует такое поведение:

$database->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...