inilim2
@inilim2
Intern PHP

MySQL PDO, Почему все значения при выборке типа string?

INSERT INTO entity_rights_links
  SET entity_type=:entity_type, id_entity=:id_entity, id_option=:id_option
  ON DUPLICATE KEY UPDATE entity_type=:entity_type

// в данном запросе 4 маски, но только 3 уникальные!

$sql = 'INSERT INTO entity_rights_links
  SET entity_type=:entity_type, id_entity=:id_entity, id_option=:id_option
  ON DUPLICATE KEY UPDATE entity_type=:entity_type';

PDO::exec($sql, [
    'entity_type' => 1, // под капотом bindParam
    'id_entity' => 5, // под капотом bindParam
    'id_option' => 20000, // под капотом bindParam
]);

// ЕСЛИ PDO::ATTR_EMULATE_PREPARES => false
// выдаст ошибку, так как в запросе 4 дырки а на вход было 3, выдаст ошибку "HY093"
// НО! При выборке выдает правильные типы данных!

// ЕСЛИ PDO::ATTR_EMULATE_PREPARES => true
// ошибок не будет, и запрос выполниться как задумывалось.
// НО! При выборке все значения всегда типа string.


И как быть?

PHP 7.4.3
MySQL 8
  • Вопрос задан
  • 112 просмотров
Пригласить эксперта
Ответы на вопрос 2
ipatiev
@ipatiev Куратор тега PHP
Потомок старинного рода Ипатьевых-Колотитьевых
Зачем вы задаёте не тот вопрос, с которым у вас проблема?:)

Ваша проблема в том, что вы хотите проэксплуатировать баг в ПДО, из-за которого он не сообщает об ошибке.
Не надо этого делать.
Передавайте ровно столько параметров, сколько "масок" в запросе. Проблема решена.
Ответ написан
Комментировать
@Akina
Сетевой и системный админ, SQL-программист.
После сохранения значения в таблице MySQL оно имеет тип того поля, в которое сохраняется, вся история потеряна, какой код и с каким флагами выполнял вставку, ни на что не влияет. Потому при выборке ну никак не может прийти другой тип данных именно от MySQL.

То есть какие-то дополнительные преобразования, изменяющие тип данных, выполняет PHP уже после того, как он получил ответ от MySQL. Или не PHP, а коннектор, который PHP использует для доступа к MySQL. Но в любом случае это происходит уже на стороне клиента.

Предположу, что эмуляция - процесс двусторонний. То есть не только на пути "туда", но и на обратном пути. Что при дополнительной обработке, которую требует настройка PDO::ATTR_EMULATE_PREPARES => true, корёжит тип данных.

На всякий случай проверьте, не вызывает ли изменение этого флага корректировки других флагов. В частности, PDO::ATTR_STRINGIFY_FETCHES.
Ответ написан
Ваш ответ на вопрос

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

Похожие вопросы