Как передать массив параметров 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 использует для привязки параметров к переменной.

Solutions Collecting From Web of "Как передать массив параметров PDO, но все же указать их типы?"

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

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

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

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

Как указано в документации для 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).

Удачи!

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

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

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