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 |
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. |
// в данном запросе 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
Дополнительно:
Ответы:
Зачем вы задаёте не тот вопрос, с которым у вас проблема?:)
Ваша проблема в том, что вы хотите проэксплуатировать баг в ПДО, из-за которого он не сообщает об ошибке.
Не надо этого делать.
Передавайте ровно столько параметров, сколько "масок" в запросе. Проблема решена.
После сохранения значения в таблице MySQL оно имеет тип того поля, в которое сохраняется, вся история потеряна, какой код и с каким флагами выполнял вставку, ни на что не влияет. Потому при выборке ну никак не может прийти другой тип данных именно от MySQL.
То есть какие-то дополнительные преобразования, изменяющие тип данных, выполняет PHP уже после того, как он получил ответ от MySQL. Или не PHP, а коннектор, который PHP использует для доступа к MySQL. Но в любом случае это происходит уже на стороне клиента.
Предположу, что эмуляция - процесс двусторонний. То есть не только на пути "туда", но и на обратном пути. Что при дополнительной обработке, которую требует настройка PDO::ATTR_EMULATE_PREPARES => true, корёжит тип данных.
На всякий случай проверьте, не вызывает ли изменение этого флага корректировки других флагов. В частности, PDO::ATTR_STRINGIFY_FETCHES.
- проверил, к сожалению "PDO::ATTR_STRINGIFY_FETCHES" не влияет на значения
- inilim2, тогда это противоречит документации, в которой чётко написано:
PDO::ATTR_STRINGIFY_FETCHES
Whether to convert numeric values to strings when fetching. Takes a value of type bool: true to enable and false to disable.
- Akina, Если отключить "ATTR_EMULATE_PREPARES" тогда "ATTR_STRINGIFY_FETCHES" преобразует значения.
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
MySQL PDO - это расширение PHP для работы с базой данных MySQL с использованием подготовленных запросов. При выборке данных из базы данных с использованием PDO, все значения по умолчанию возвращаются в виде строк (string). Это происходит потому, что PDO не приводит значения к определенному типу данных, а оставляет их в виде строк для дальнейшей обработки программой.
Значения возвращаются в виде строк, потому что PDO не знает заранее, какой тип данных содержится в каждом столбце таблицы. При использовании PDO, программист должен самостоятельно приводить значения к нужному типу данных, если это необходимо. Например, если мы знаем, что значение в столбце таблицы должно быть числом, мы можем преобразовать строку в число с помощью функции intval() или floatval().
Кроме того, при использовании PDO можно указать тип данных, который ожидается возвращать в запросе, с помощью метода bindColumn(). Например, если мы ожидаем, что значение будет числом, мы можем указать тип данных "PDO::PARAM_INT" для этого столбца и PDO автоматически преобразует значение в число.
Таким образом, все значения при выборке типа string в MySQL PDO из-за того, что PDO не приводит значения к определенному типу данных. Программисту необходимо самостоятельно обрабатывать значения и приводить их к нужному типу данных, если это необходимо.