bigint truncado a través de PDO?

Me encontré con un problema con el almacenamiento de un entero grande en una columna BIGINT en MySQL a través de PDO

Si ejecuto esta prueba:

 $number = "30123456789"; var_dump($number); //prints string(11) "30123456789" $new_number = (int)$number; var_dump($new_number); //prints int(30123456789) 

Hasta aquí todo bien…

Si ejecuto este SQL directamente en MySQL:

 update my_table set bigint_field = 30123456789 where id_field = 1 

Todo funciona bien …

El problema surge cuando trato de guardar ese número a través de PDO y reduje el problema a esta línea de código:

 //parameterized query //update my_table set bigint_field = :bigint_field where id_field = :id_field $statement->bindValue(":bigint_field", $new_number, PDO::PARAM_INT); 

Si el parámetro de tercer type opcional está ausente o es igual a PDO::PARAM_STR , el valor se guarda, pero el valor se trunca a 58685709. Si bash guardar 20288976024, el valor se trunca a 0. ¿Qué está pasando aquí?

Estoy ejecutando PHP 5.5.33 y MySQL 5.6.25 en Debian Wheezy x64

No puedo reproducir tu caso.

En un sistema x86 intval () ya hace 2147483647 En un sistema de 64 bits todo funciona bien.

El enlace de valores de bigint como cadenas puede generar resultados incorrectos, ya que el valor se convertirá en un flotante y perderá precisión.

Editar: resultó ser un viejo problema libmysql. Habiendo configurado PHP de esta manera, pude reproducir el problema:

 $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()); 

imprime

 int(30123456789) int(20288976024) [{"i":"58685717"},{"i":"0"} 

Dos posibles soluciones:

  1. (Preferido) Instale php-mysqlnd , que debe hacer de todos modos, porque mysqlnd es un nuevo reemplazo para el antiguo conector libmysql.
  2. Activa el modo de emulación: una consulta que está construida por PDO también funciona sin errores.