PHP: как кодировать бесконечности или числа NaN для JSON?

По-видимому, бесконечность и 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"; 

Производит следующее:

 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} 

Есть ли способ правильно кодировать эти числа без написания моей собственной функции json_encode() ? Может быть, обходной путь?

Согласно спецификации JSON, нет значений Infinity или NaN: http://json.org/

обходные:

  1. Откажитесь от использования JSON (чистый JSON) и напишите свою собственную функцию json_encode, которая будет обрабатывать INF / NAN (преобразование в «бесконечность» и «NaN» соответственно) и убедитесь, что вы разбираете JSON, используя что-то вроде result = eval('(' + json + ')'); на стороне клиента.

  2. Предварительно преобразуйте значения IFN / NAN в строковые значения («Бесконечность» и «NaN»), и когда вы собираетесь работать с этими значениями в JavaScript, используйте следующую конструкцию: var number1 = (+numbers.positive_infinity); , Это преобразует строковое значение «Бесконечность» в числовое представление Infinity .

Это, на мой взгляд, большой недостаток JSON. Различные кодеры JSON обрабатывают это по-другому, краткий обзор можно найти здесь: http://lavag.org/topic/16217-cr-json-labview/?p=99058

Одним из решений является кодирование + inf как + 1e9999, поскольку в большинстве декодеров естественным образом переполняется до + inf, а также с -inf как -1e9999. NaN намного сложнее.

Вы правы в спецификации JSON :

Числовые значения, которые не могут быть представлены в виде последовательностей цифр (например, Бесконечность и NaN), не допускаются.

Решение также должно исходить из спецификации, так как пользовательский кодер «JSON» в любом случае не выдавал бы действительный JSON (вам также придется писать собственный декодер, а затем вы и потребители ваших данных будут вынуждены использовать это до тех пор, пока конец времени).

Вот, что спецификация позволяет использовать значения:

Значение JSON ДОЛЖНО быть объектом, массивом, числом или строкой или одним из следующих трех буквенных имен:

 false null true 

Таким образом, любое обходное решение, которое включает законный JSON вместо обычного JSON-подобного протокола, предполагает использование чего-то другого вместо чисел.

Одним из разумных вариантов было бы использование строк "Infinity" и "NaN" для этих краевых случаев.

Предупреждение, упомянутое выше, есть официальная ошибка, о которой сообщается в документации php.

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

В качестве обновления для читателей этого вопроса для более новых версий PHP> = 5.5.0, чтобы получить значения INF или NAN из json_encode которые будут закодированы как 0 а не json_encode которые вообще не будут выводиться, добавьте параметр JSON_PARTIAL_OUTPUT_ON_ERROR .

В качестве примера: json_encode($data, JSON_NUMERIC_CHECK | JSON_PARTIAL_OUTPUT_ON_ERROR);