Подтвердить что ты не робот

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()? Может быть, обходной путь?

4b9b3361

Ответ 1

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

Обходные:

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

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

Ответ 2

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

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

Ответ 3

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

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

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

Вот что специфицирует спецификацию:

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

false null true

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

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

Ответ 4

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

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

Ответ 5

Как обновление для читателей этого вопроса для более новых версий 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);