PHP:如何将无穷大或NaN数字编码为JSON?

时间:2021-02-27 22:57:07

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

显然,infinity和NaN不是JSON规范的一部分,因此PHP代码:

$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?

有什么方法可以在不编写自己的json_encode()函数的情况下正确地编码这些数字吗?也许一些解决方法吗?

5 个解决方案

#1


7  

According to JSON spec, there is no Infinity or NaN values: http://json.org/

根据JSON规范,没有无穷大或NaN值:http://json.org/。

Workarounds:

解决方法:

  1. 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.

    拒绝使用JSON(纯JSON),编写自己的json_encode函数,该函数将处理INF/NAN(分别转换为“Infinity”和“NAN”),并确保使用result = eval('(' + JSON + ')'之类的东西解析JSON;在客户端。

  2. 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 numeric Infinity representation.

    将IFN/NAN值预先转换为字符串值('Infinity'和' NAN '),当您要在JavaScript中使用这些值时,使用以下结构:var number1 = (+numbers.positive_infinity);这将把字符串值'Infinity'转换成数值无穷大表示。

#2


10  

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

在我看来,这是JSON的一大缺点。不同的JSON编码器处理这种方式的方式不同,可以在这里找到一个快速的概述: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.

一种解决方案是将+inf编码为+1e9999,因为在大多数解码器中,+inf自然会溢出到+inf,而-inf也会溢出到-1e9999。南要困难得多。

#3


9  

You are right about the JSON spec:

您对JSON规范的看法是正确的:

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

不能表示为数字序列的数值(如无穷大和NaN)是不允许的。

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).

解决方案也必须来自规范,因为自定义“JSON”编码器不会生成有效的JSON(您还必须编写自定义解码器,然后您和数据的使用者将*使用它,直到时间结束)。

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:

JSON值必须是对象、数组、数字或字符串,或以下三个文字名称中的一个:

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.

因此,任何涉及合法的JSON而不是类似于JSON的自定义协议的解决方案都会涉及到使用其他东西而不是数字。

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

一个合理的选择是使用字符串“∞”和“NaN”来表示这些边的情况。

#4


0  

The warning mentioned above, there is official bug reported in php documentation.

上面提到的警告,php文档中报告了官方的错误。

https://bugs.php.net/bug.php?id=64695

https://bugs.php.net/bug.php?id=64695

#5


0  

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.

更新后的PHP >= 5.5.0版本的读者,为了让json_encode的INF或NAN值编码为0,而不是json_encode根本没有输出,添加JSON_PARTIAL_OUTPUT_ON_ERROR选项。

As an example: json_encode($data, JSON_NUMERIC_CHECK | JSON_PARTIAL_OUTPUT_ON_ERROR);

例如:json_encode($data, JSON_NUMERIC_CHECK | JSON_PARTIAL_OUTPUT_ON_ERROR);

#1


7  

According to JSON spec, there is no Infinity or NaN values: http://json.org/

根据JSON规范,没有无穷大或NaN值:http://json.org/。

Workarounds:

解决方法:

  1. 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.

    拒绝使用JSON(纯JSON),编写自己的json_encode函数,该函数将处理INF/NAN(分别转换为“Infinity”和“NAN”),并确保使用result = eval('(' + JSON + ')'之类的东西解析JSON;在客户端。

  2. 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 numeric Infinity representation.

    将IFN/NAN值预先转换为字符串值('Infinity'和' NAN '),当您要在JavaScript中使用这些值时,使用以下结构:var number1 = (+numbers.positive_infinity);这将把字符串值'Infinity'转换成数值无穷大表示。

#2


10  

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

在我看来,这是JSON的一大缺点。不同的JSON编码器处理这种方式的方式不同,可以在这里找到一个快速的概述: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.

一种解决方案是将+inf编码为+1e9999,因为在大多数解码器中,+inf自然会溢出到+inf,而-inf也会溢出到-1e9999。南要困难得多。

#3


9  

You are right about the JSON spec:

您对JSON规范的看法是正确的:

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

不能表示为数字序列的数值(如无穷大和NaN)是不允许的。

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).

解决方案也必须来自规范,因为自定义“JSON”编码器不会生成有效的JSON(您还必须编写自定义解码器,然后您和数据的使用者将*使用它,直到时间结束)。

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:

JSON值必须是对象、数组、数字或字符串,或以下三个文字名称中的一个:

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.

因此,任何涉及合法的JSON而不是类似于JSON的自定义协议的解决方案都会涉及到使用其他东西而不是数字。

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

一个合理的选择是使用字符串“∞”和“NaN”来表示这些边的情况。

#4


0  

The warning mentioned above, there is official bug reported in php documentation.

上面提到的警告,php文档中报告了官方的错误。

https://bugs.php.net/bug.php?id=64695

https://bugs.php.net/bug.php?id=64695

#5


0  

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.

更新后的PHP >= 5.5.0版本的读者,为了让json_encode的INF或NAN值编码为0,而不是json_encode根本没有输出,添加JSON_PARTIAL_OUTPUT_ON_ERROR选项。

As an example: json_encode($data, JSON_NUMERIC_CHECK | JSON_PARTIAL_OUTPUT_ON_ERROR);

例如:json_encode($data, JSON_NUMERIC_CHECK | JSON_PARTIAL_OUTPUT_ON_ERROR);