Я столкнулся с проблемой хранения большого целого числа в столбце 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 как строки может привести к неправильным результатам, так как значение будет передано в float и потеряет точность.
Редактировать: он оказался старой проблемой 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
, который вам все равно придется делать, потому что mysqlnd является новой заменой для старого соединителя libmysql.