урезать бигинт через 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

8

Решение

Я не могу воспроизвести ваш случай.

В системе 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"}

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

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

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]