Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP json sometimes converts float numbers to integer

Tags:

json

php

Given a float number, after a json encoding and a subsequent decoding, the variable type float (or double) sometimes it's not preserved.

$n1 = 1.23;
$json = json_encode($n1); // '1.23'
$n2 = json_decode($json);

$t1 = gettype($n1); // 'double'
$t2 = gettype($n2); // 'double'

$d = $n1 === $n2; // true

However, when decimals are '0' the result is different:

$n1 = 1.0;
$json = json_encode($n1); // '1'
$n2 = json_decode($json);

$t1 = gettype($n1); // 'double'
$t2 = gettype($n2); // 'integer'

$d = $n1 === $n2; // false

I have to conclude that the behaviour of the json encode / decode functions is based on data value, therefore hard to predict, and ultimately quite inconsistent.

Is there any way to ensure to preserve the type of the variable during the json encode / decode process?

like image 842
Demis Palma ツ Avatar asked Aug 07 '17 09:08

Demis Palma ツ


1 Answers

The JSON format on its own, has no notion of floats and integers, it just has numbers. This is one of the reasons why it is a language-independent data format.

However, I've found that the json_encode option JSON_PRESERVE_ZERO_FRACTION does the trick.

JSON_PRESERVE_ZERO_FRACTION

Ensures that float values are always encoded as a float value. Available since PHP 5.6.6.

It forces json_encode to always put at least a '0' decimal digit to the JSON notation.

json_decode, for its part, is natively able to interpret numbers with decimal digits into float, and it doesn't need any special flag.

$n1 = 1.0;
$json = json_encode($n1, JSON_PRESERVE_ZERO_FRACTION); // '1.0'
$n2 = json_decode($json);

$t1 = gettype($n1); // 'double'
$t2 = gettype($n2); // 'double'

$d = $n1 === $n2; // true
like image 200
Demis Palma ツ Avatar answered Nov 09 '22 11:11

Demis Palma ツ