Очевидно, что бесконечность и 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/
обходные:
Откажитесь от использования JSON (чистый JSON) и напишите свою собственную функцию json_encode, которая будет обрабатывать INF / NAN (преобразование в «Бесконечность» и «NaN» соответственно), и убедитесь, что вы анализируете JSON, используя что-то вроде result = eval('(' + json + ')');
на стороне клиента.
Предварительно преобразуйте значения IFN / NAN в строковые значения («Бесконечность» и «NaN»), и когда вы собираетесь работать с этими значениями в JavaScript, используйте следующую конструкцию: var number1 = (+numbers.positive_infinity);
, Это преобразует строковое значение Infinity в числовое значение. Infinity
представление.
На мой взгляд, это большой недостаток JSON. Различные кодировщики JSON обрабатывают это по-разному, краткий обзор можно найти здесь: http://lavag.org/topic/16217-cr-json-labview/?p=99058
Одно из решений состоит в том, чтобы кодировать + inf как + 1e9999, так как это естественным образом переполнится до + inf в большинстве декодеров, и то же самое с -inf как -1e9999. NaN намного сложнее.
Вы правы насчет JSON spec:
Числовые значения, которые не могут быть представлены в виде последовательности цифр (например, Infinity и NaN), не допускаются.
Решение также должно исходить из спецификации, так как пользовательский кодер «JSON» в любом случае не будет генерировать допустимый JSON (вам также придется написать собственный декодер, и тогда вы и потребители ваших данных будете вынуждены использовать его до тех пор, пока конец времени).
Вот что спецификация допускает для значений:
Значение JSON ДОЛЖНО быть объектом, массивом, числом или строкой или одним из следующих трех литеральных имен:
false null true
Таким образом, любой обходной путь, который включает в себя юридический JSON вместо пользовательского JSON-подобного протокола, будет включать использование чего-то другого вместо чисел.
Одним разумным вариантом будет использование строк "Infinity"
а также "NaN"
для этих крайних случаев.
В упомянутом выше предупреждении есть официальная ошибка в документации php.
В качестве обновления для читателей этого вопроса для более новых версий 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);