bigint усечен через PDO?

Я столкнулся с проблемой хранения большого целого числа в столбце 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"} 

Два возможных решения:

  1. (Предпочитаемый) Установите php-mysqlnd , который вам все равно придется делать, потому что mysqlnd является новой заменой для старого соединителя libmysql.
  2. Включите режим эмуляции ON – запрос, созданный PDO, также работает безупречно.