Почему PDO_MySQL не возвращает целое число?

Я переношу свои PHP-коды из mysql (устарел в 5.5) на PDO_MySQL. Однако mysql_fetch_row возвращает целое число, а PDOStatement::fetch возвращает строки для чисел. Как я могу заставить PDO вести себя так же, как и предыдущий?

Результат mysql_fetch_row:

array(1) {
  ["id"]=>
  int(1)
}

Результат PDOStatement::fetch:

array(1) {
  ["id"]=>
  string(1) "1"
}

Ответ 1

Установите PDO::ATTR_EMULATE_PREPARES в значение false, если вам действительно нужно это с нестандартным PHP

Если mysql_fetch_row возвращает значение int для SUM (мне никогда не приходилось проверять) - тогда он делает какую-то магию как if (ctype_digit($val)) $row[$key] = (int)$val; - поэтому вы можете сделать это в своем DBAL

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

Похоже, что сервер может возвращать данные в 2 форматах - native и mysqlnd, зависит от типа запроса. Последний может быть интерпретирован библиотекой-клиентом для выдачи результирующего значения.

Ответ 2

Для записей PDO предоставляет функцию, которая изменила бы это, PDO::ATTR_STRINGIFY_FETCHES:

Преобразование числовых значений в строки при извлечении. Требуется bool.

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

К несчастью, драйвер MySQL не поддерживает его:

<?php

$pdo = new PDO('mysql:host=localhost;dbname=test', 'test', 'test');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$pdo->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);
$sql = 'SELECT 1 AS integer_number, 3.14 AS floating_point';
$res = $pdo->query($sql);
while($row = $res->fetch(PDO::FETCH_ASSOC)){
    var_dump($row);
}

 

array(2) {
  ["integer_number"]=>
  string(1) "1"
  ["floating_point"]=>
  string(4) "3.14"
}