2012-11-27 11 views
13

A quanto pare, l'infinito e NaN non sono una parte della specifica JSON, quindi questo codice PHP:PHP: Come codificare numeri infinito o NaN in JSON?

$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"; 

Produce questo:

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} 

non v'è alcun modo per codificare correttamente questi numeri senza scrivere il mio json_encode() funzione? Forse qualche soluzione?

risposta

7

Secondo JSON spec, non v'è alcun valore infinito o NaN valori: http://json.org/

Soluzioni alternative:

  1. Rifiuta utilizzando JSON (puro JSON), e scrivere la propria funzione json_encode, che si occuperà INF/NAN (convertendosi rispettivamente a "Infinity" e "NaN") e assicurati di analizzare JSON utilizzando qualcosa come result = eval('(' + json + ')'); sul lato client.

  2. Pre convertire i valori IFN/NAN in valori stringa ('Infinity' e 'NaN'), e quando si intende operare con quei valori in JavaScript, utilizzare la seguente struttura: var number1 = (+numbers.positive_infinity);. Questo convertirà il valore stringa 'Infinity' in una rappresentazione numerica di Infinity.

9

Hai ragione circa la JSON spec:

valori numerici che non possono essere rappresentati come non sono ammessi sequenze di cifre (ad esempio Infinity e NaN).

La soluzione deve venire anche dalla specifica, dal momento che un custom "JSON" encoder non produrrebbe JSON valido in ogni caso (si avrebbe dovuto scrivere un decoder personalizzato come bene, e poi si e consumatori di dati sarebbe costretto a usarlo fino alla fine dei tempi).

Qui' ciò che le specifiche permette di valori:

Un valore JSON deve essere un oggetto, matrice, numero o stringa, o uno dei seguenti tre letterali:

false null true 

Pertanto, qualsiasi soluzione alternativa che implichi un JSON legale anziché un protocollo personalizzato simile a JSON implicherebbe l'uso di qualcos'altro invece dei numeri.

Un'opzione ragionevole sarebbe quella di utilizzare le stringhe "Infinity" e "NaN" per questi casi limite.

+1

+1 per citare le specifiche e menzionando letterali. Accettare l'altra risposta, tuttavia, perché suggerisce il modo di riconvertirle in numeri. – Septagram

10

Questa è a mio avviso una grande mancanza di JSON. Diversi encoder JSON gestiscono diversamente, una rapida panoramica può essere trovata qui: http://lavag.org/topic/16217-cr-json-labview/?p=99058

Una soluzione è quella di codificare + inf come + 1e9999 in quanto sarà naturalmente overflow a + inf nella maggior parte dei decodificatori e lo stesso con -inf come -1e9999 . NaN è molto più difficile.

0

come aggiornamento per i lettori di questa domanda per le nuove versioni di PHP> = 5.5.0, per ottenere INF o NAN valori da json_encode da codificare come 0 piuttosto che json_encode mancato l'uscita a tutti, aggiungi l'opzione JSON_PARTIAL_OUTPUT_ON_ERROR.

Ad esempio: json_encode($data, JSON_NUMERIC_CHECK | JSON_PARTIAL_OUTPUT_ON_ERROR);