Я столкнулся с проблемой хранения большого целого числа в BIGINT
колонка на MySQL через PDO
Если я запускаю этот тест:
$number = "30123456789";
var_dump($number); //prints string(11) "30123456789"
$new_number = (int)$number;
var_dump($new_number); //prints int(30123456789)
Все идет нормально…
Если я запускаю этот SQL напрямую в MySQL:
update my_table set bigint_field = 30123456789 where id_field = 1
Все отлично работает …
Проблема возникает, когда я пытаюсь сохранить это число через PDO, и я уменьшил проблему до этой строки кода:
//parameterized query
//update my_table set bigint_field = :bigint_field where id_field = :id_field
$statement->bindValue(":bigint_field", $new_number, PDO::PARAM_INT);
Если необязательный третий type
параметр отсутствует или равен PDO::PARAM_STR
тогда значение сохраняется просто отлично, если не значение обрезается до 58685709. Если я пытаюсь сохранить 20288976024, значение обрезается до 0. Что здесь происходит
Я использую PHP 5.5.33 и MySQL 5.6.25 на Debian Wheezy x64
Я не могу воспроизвести ваш случай.
В системе x86 intval () уже составляет 2147483647
В 64-битной системе все работает нормально.
Связывание значений bigint в виде строк может привести к неверным результатам, так как значение будет приведено к плавающей запятой и потеряет точность.
Редактировать: это оказалось старой проблемой libmysql. Настроив PHP таким образом, я смог воспроизвести проблему:
$number = 30123456789;
$new_number = 20288976024;
var_dump($number, $new_number);
$pdo->query("CREATE TEMPORARY TABLE bint_test(i BIGINT unsigned)");
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
$stmt = $pdo->prepare("insert into bint_test values (?)");
$stmt->bindValue(1, $number, PDO::PARAM_INT);
$stmt->execute();
$stmt->bindValue(1, $new_number, PDO::PARAM_INT);
$stmt->execute();
echo json_encode($pdo->query("SELECT * FROM bint_test")->fetchAll());
распечатывает
int(30123456789)
int(20288976024)
[{"i":"58685717"},{"i":"0"}
Два возможных решения:
php-mysqlnd
, что вы должны сделать в любом случае, потому что MySQL является новой заменой старого коннектора libmysql. Других решений пока нет …