Подтвердить что ты не робот

Как передать массив параметров PDO, но все же указать их типы?

$sql = "SELECT * FROM table WHERE id LIKE CONCAT('%', :id, '%')
LIMIT :limit1, :limit2";

Я хочу использовать вход массива следующим образом:

$stmt->execute($array);

В противном случае я не могу повторно использовать тот же метод для выполнения моих запросов.

В то же время: limit1 и: limit2 не работают, если они не помещаются следующим образом:

$stmt->bindParam(':limit1', $limit1, PDO::PARAM_INT);

Я попытался сделать оба, но не выполняет с bindParams:

$stmt->bindParam(':limit2', $limit2, PDO::PARAM_INT);
$stmt->execute($array);

Каким образом это возможно?

Я думал, что могу расширить PDOStatement и добавить новый метод "bindLimit" или что-то подобное, но я не могу понять, какой внутренний метод PDO использует для привязки параметров к переменной.

4b9b3361

Ответ 1

Если вы отключите настройку по умолчанию PDO::ATTR_EMULATE_PREPARES, тогда она будет работать. Я только узнал, что эта настройка включена по умолчанию для mysql, что означает, что вы никогда не используете готовые инструкции, php внутренне создает динамический sql для вас, цитируя значения для вас и заменяя заполнители. Ya, крупный wtf.

$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$stmt = $pdo->prepare($sql);
$stmt->execute(array(5)); //works!

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

См. также PDO MySQL: используйте PDO:: ATTR_EMULATE_PREPARES или нет?

Ответ 2

Как указано в документации для PDOStatement::execute:

input_parameters

Массив значений с таким количеством элементов, как в выполняемом операторе SQL есть связанные параметры. Все значения считаются PDO::PARAM_STR.

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

В вашем случае MySQL пытается выполнить предложение LIMIT, которое имеет строковые аргументы. Хотя он может попытаться разрешить это, используя его неявное преобразование типа, так как везде везде появляется строка, где должно быть целое число, просто не беспокоит и убегает вместо этого плачет.

Итак, вам нужно сообщить PDO, что эти конкретные параметры являются целыми числами. Поскольку даже PHP не знает, какой тип его переменных, я считаю, что единственный способ сделать это - напрямую связать их с PDOStatement::bindParam или PDOStatement::bindValue, как вы это делаете (хотя не обязательно указывать аргумент $data_type в качестве простого (int) приведения $variable, дает PHP иначе непонятную систему типов достаточно для работы).

Что касается внутреннего метода PDO, используемого для привязки параметров к переменной, обращайтесь к really_register_bound_param() (неудивительно, что не подвергается PHP, будем веселиться на C).

Удачи!

Ответ 3

Зачем связывать предельные значения, когда они не введены пользователем?

$start = 0;
$limit = 20;
$sql = "SELECT * FROM table WHERE id LIKE CONCAT('%', :id, '%')
    LIMIT $start, $limit";

Даже если $start и $limit определяются из пользовательского ввода, скажем, от $_GET, вы можете проверить значение с помощью is_int().