Для чего нужно использовать парметр PDO::PARAM_INT в функции bindParam() ?

Взять к примеру такие строки:
$sth = $dbh->prepare('SELECT * FROM fruit WHERE calories < ? AND colour = ?');
$sth->bindParam(1, $_POST['calories'], PDO::PARAM_INT);
$sth->bindParam(2, $_POST['colour'], PDO::PARAM_STR);


Поля в таблице имеют типы int(11) и text соответственно. Если число будет намеренно испорчено на клиенте, то оно не сохранятся в базе, а провести инъекцию через PDO, как я понял, нельзя.

Так для чего нужно использовать параметры PDO::PARAM_INT и PDO::PARAM_STR при передаче значений переменных в запрос? Что тут можно такого вредного и неправильного передать в базу?

UPDATE

конечно же, в настройках соединения прописано
PDO::ATTR_EMULATE_PREPARES => false
  • Вопрос задан
  • 4014 просмотров
Пригласить эксперта
Ответы на вопрос 3
FanatPHP
@FanatPHP
Чебуратор тега РНР
Для начала ответим на вопрос буквально:

конечно же, в настройках соединения прописано
PDO::ATTR_EMULATE_PREPARES => false
В этом случае - вообще незачем.
Если эмуляция отключена, то можно вообще никогда не указывать тип.

Правда, насчет "конечно" ты поторопился. Ничего "конечного" в отключении эмуляции нет - оба варианта одинаково безопасные.

И вот если эмуляцию включить, то как раз и возникнет единственный случай, когда придется биндить с указанием типа: если у тебя в запросе передаются параметры в LIMIT. Если в запросе есть оператор LIMIT и в него передаются параметры, то их надо обязательно биндить через PDO::PARAM_INT - иначе запрос выдаст ошибку.
Мало того - передаваемые данные надо самостоятельно привести к типу int - PDO это за тебя делать не будет!

Теперь ответим в общем, объясняя твои многочисленные заблуждения:

  1. Как тебе уже объяснили выше, инъекция - это не про сохранение в базе. Это именно про выполнение запроса. Так что тип поля в БД не имеет значения.
  2. Инъекцию через PDO провести нельзя только если на 100% соблюдается условие "любые данные попадают в запрос только через плейсхолдеры" - просто самим фактом своего присутствия PDO ничего ни от кого не защищает. Кстати, соблюдение этого правила не так просто, как кажется. Решение для большинства нетривиальных случаев можно посмотреть здесь: phpfaq.ru/pdo
  3. Самое важное: если мы используем плейсхолдеры, то все остальное уже неважно. Указывай какой хочешь тип, или не указывай вовсе - инъекции не будет. То есть, к безопасности твой вопрос про указание типа отношения не имеет.
  4. Если ты не указал тип, то по умолчанию берется PDO::PARAM_STR. Это очень удобно, поскольку БД (по крайней мере - mysql) всегда корректно обработает любые данные, если они переданы, как строки

Так что, я думаю, что ты теперь и сам можешь ответить на вопрос, "зачем указывать тип".
И будешь писать просто
$sth = $dbh->prepare('SELECT * FROM fruit WHERE calories < ? AND colour = ?');
$sth->execute([$_POST['calories'],$_POST['colour']]);
Ответ написан
PDO::PARAM_INT говорит о том, что $_POST['calories'] является числом.
PDO::PARAM_STR говорит о том, что $_POST['colour'] является строкой.
Ответ написан
Sanasol
@Sanasol Куратор тега PHP
нельзя просто так взять и загуглить ошибку
инъекция и не должна сохраняться в базу. Он один раз отработала и всё.
передадут вам вместо $_POST['colour']
Что-то вроде
red'; drop database information_schema;
Выполнятся оба запроса и печаль наступит.

Поэтому вы указываете какого типа должна быть переменная, и ПДО её экранирует так чтобы не произошло гадостей.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы