问题
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?
回答1:
According to JSON spec, there is no Infinity or NaN values: http://json.org/
Workarounds:
Reject using JSON (pure JSON), and write your own json_encode function, which will handle INF/NAN (converting to "Infinity" and "NaN" respectively), and make sure you are parsing JSON using something like
result = eval('(' + json + ')');
on the client side.Pre convert your IFN/NAN values into string values ('Infinity' and 'NaN'), and when you are going to operate with those values in JavaScript, use the following construction:
var number1 = (+numbers.positive_infinity);
. This will convert string value 'Infinity' into numericInfinity
representation.
回答2:
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.
回答3:
This is in my opinion a big shortcoming of JSON. Different JSON encoders handle this differently, a quick overview can be found here: http://lavag.org/topic/16217-cr-json-labview/?p=99058
One solution is to encode +inf as +1e9999 as that will naturally overflow to +inf in most decoders, and same with -inf as -1e9999. NaN is much harder.
回答4:
As an update to readers of this question for newer versions of PHP >= 5.5.0, to get INF
or NAN
values from json_encode
to be encoded as 0
rather than json_encode
failing to output at all, add the JSON_PARTIAL_OUTPUT_ON_ERROR option.
As an example: json_encode($data, JSON_NUMERIC_CHECK | JSON_PARTIAL_OUTPUT_ON_ERROR);
回答5:
The warning mentioned above, there is official bug reported in php documentation.
https://bugs.php.net/bug.php?id=64695
来源:https://stackoverflow.com/questions/13581843/php-how-to-encode-infinity-or-nan-numbers-to-json