PHP: How to encode infinity or NaN numbers to JSON?

Septagram picture Septagram · Nov 27, 2012 · Viewed 17.5k times · Source

Apparently, infinity and NaN are not a part of JSON specification, so this PHP code:

$numbers = array();
$numbers ['positive_infinity'] = +INF;
$numbers ['negative_infinity'] = -INF;
$numbers ['not_a_number'] = NAN;
$array_print = print_r ($numbers, true);
$array_json = json_encode ($numbers);
echo "\nprint_r(): $array_print";
echo "\njson_encode(): $array_json";

Produces this:

PHP Warning:  json_encode(): double INF does not conform to the JSON spec, encoded as 0 in /home/septi/test.php on line 8
PHP Warning:  json_encode(): double -INF does not conform to the JSON spec, encoded as 0 in /home/septi/test.php on line 8
PHP Warning:  json_encode(): double NAN does not conform to the JSON spec, encoded as 0 in /home/septi/test.php on line 8

print_r(): Array
(
    [positive_infinity] => INF
    [negative_infinity] => -INF
    [not_a_number] => NAN
)

json_encode(): {"positive_infinity":0,"negative_infinity":0,"not_a_number":0}

Is there any way to correctly encode these numbers without writing my own json_encode() function? Maybe some workaround?

Answer

Jon picture Jon · Nov 27, 2012

You are right about the JSON spec:

Numeric values that cannot be represented as sequences of digits (such as Infinity and NaN) are not permitted.

The solution must also come from the spec, since a custom "JSON" encoder would not produce valid JSON anyway (you would have to write a custom decoder as well, and then you and consumers of your data would be forced to use that until the end of time).

Here' what the spec allows for values:

A JSON value MUST be an object, array, number, or string, or one of the following three literal names:

false null true

So, any workaround that involves legal JSON instead of a custom JSON-like protocol would involve using something else instead of numbers.

One reasonable option would be to use the strings "Infinity" and "NaN" for these edge cases.