web-dev-qa-db-ja.com

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()関数を記述せずに、これらの数値を正しくエンコードする方法はありますか?多分いくつかの回避策?

18
Septagram

JSON仕様によると、InfinityまたはNaNの値はありません: http://json.org/

回避策:

  1. JSON(純粋なJSON)を使用して拒否し、INF/NAN(それぞれ「Infinity」と「NaN」に変換)を処理する独自のjson_encode関数を記述し、result = eval('(' + json + ')');などを使用してJSONを解析していることを確認します。クライアント側で。

  2. IFN/NAN値を文字列値(「Infinity」および「NaN」)に事前に変換し、JavaScriptでこれらの値を操作する場合は、次の構文を使用します:var number1 = (+numbers.positive_infinity);。これにより、文字列値 'Infinity'が数値のInfinity表現に変換されます。

10
mdevils

あなたは正しいです JSON仕様

数字のシーケンスとして表すことができない数値(InfinityやNaNなど)は許可されていません。

カスタムの「JSON」エンコーダーはとにかく有効なJSONを生成しないため、ソリューションも仕様に基づいている必要があります(カスタムデコーダーも作成する必要があります。そうすると、データの消費者とそのユーザーは、終了、時間切れ)。

仕様で値が許可されているものは次のとおりです。

JSON値は、オブジェクト、配列、数値、文字列、または次の3つのリテラル名のいずれかである必要があります。

false null true

したがって、カスタムJSONのようなプロトコルの代わりに正当なJSONを使用する回避策には、数値の代わりに別のものを使用する必要があります。

妥当なオプションの1つは、これらのエッジの場合に文字列"Infinity"および"NaN"を使用することです。

11
Jon

これは私の意見ではJSONの大きな欠点です。異なるJSONエンコーダーはこれを異なる方法で処理します。簡単な概要はここにあります: http://lavag.org/topic/16217-cr-json-labview/?p=99058

1つの解決策は、+ infを+ 1e9999としてエンコードすることです。これは、ほとんどのデコーダーで+ infに自然にオーバーフローし、-infと同じように-1e9999です。 NaNははるかに困難です。

10
emilk

上記の警告、phpドキュメントで報告された公式のバグがあります。

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

0
Manjunath Reddy

PHP> = 5.5.0の新しいバージョンに関するこの質問の読者への更新として、_json_encode_からINFまたはNANの値を取得します。 _0_がまったく出力に失敗するのではなく、_json_encode_としてエンコードするには、 JSON_PARTIAL_OUTPUT_ON_ERROR オプションを追加します。

例として:json_encode($data, JSON_NUMERIC_CHECK | JSON_PARTIAL_OUTPUT_ON_ERROR);

0
Sean Fahey