PHP json_decode () restituisce NULL con JSON valido?


104

Ho questo oggetto JSON memorizzato su un file di testo normale:

{
    "MySQL": {
        "Server": "(server)",
        "Username": "(user)",
        "Password": "(pwd)",
        "DatabaseName": "(dbname)"
    },
    "Ftp": {
        "Server": "(server)",
        "Username": "(user)",
        "Password": "(pwd)",
        "RootFolder": "(rf)"
    },
    "BasePath": "../../bin/",
    "NotesAppPath": "notas",
    "SearchAppPath": "buscar",
    "BaseUrl": "http:\/\/montemaiztusitio.com.ar",
    "InitialExtensions": [
        "nem.mysqlhandler",
        "nem.string",
        "nem.colour",
        "nem.filesystem",
        "nem.rss",
        "nem.date",
        "nem.template",
        "nem.media",
        "nem.measuring",
        "nem.weather",
        "nem.currency"
    ],
    "MediaPath": "media",
    "MediaGalleriesTable": "journal_media_galleries",
    "MediaTable": "journal_media",
    "Journal": {
        "AllowedAdFileFormats": [
            "flv:1",
            "jpg:2",
            "gif:3",
            "png:4",
            "swf:5"
        ],
        "AdColumnId": "3",
        "RSSLinkFormat": "%DOMAIN%\/notas\/%YEAR%-%MONTH%-%DAY%\/%TITLE%/",
        "FrontendLayout": "Flat",
        "AdPath": "ad",
        "SiteTitle": "Monte Maíz: Tu Sitio",
        "GlobalSiteDescription": "Periódico local de Monte Maíz.",
        "MoreInfoAt": "Más información aquí, en el Periódico local de Monte Maíz.",
        "TemplatePath": "templates",
        "WeatherSource": "accuweather:SAM|AR|AR005|MONTE MAIZ",
        "WeatherMeasureType": "1",
        "CurrencySource": "cotizacion-monedas:Dolar|Euro|Real",
        "TimesSingular": "vez",
        "TimesPlural": "veces"
    }
}

Quando provo a decodificarlo con json_decode(), restituisce NULL. Perché? Il file è leggibile (ho provato l'eco file_get_contents()e ha funzionato bene).

Ho testato JSON su http://jsonlint.com/ ed è perfettamente valido.

Cosa c'è che non va qui?

Soluzione

Alla ricerca di risposte su Google, sono tornato a SO: json_decode restituisce NULL dopo la chiamata al servizio web . Il mio file JSON aveva la sequenza UTF BOM (alcuni caratteri binari che non dovrebbero essere presenti), quindi interrompendo la struttura JSON. Sono andato in Hex Editor, ho cancellato i byte. È tornato tutto normale. Perché è successo? Perché ho modificato il file utilizzando il Blocco note di Microsoft Windows. Pessima idea!


5
Lavorare con PHP 5.2.9; quindi, non posso usare json_last_error().
Joel A. Villarreal Bertoldi

1
Nota anche che questo può accadere con altri caratteri non validi nel mezzo del file. Ho appena avuto json_decode () che restituiva null perché la stringa conteneva uno di quei trattini speciali, probabilmente incollati da MS Word e quindi forse codificati in modo errato. Per identificare potenziali caratteri problematici, apri il file JSON (che ho usato in Notepad ++), modifica la codifica (senza convertire) e salva come copia. Quindi diff i due file (ho usato WinMerge).
LinusR

(Problema Blocco note di Windows) Si prega di consultare questo, ho condiviso il problema troppo ed è riparato: stackoverflow.com/questions/10290849/...
Felix Aballí


Per me, non era niente di speciale, solo una virgola in più alla fine dell'elemento di un oggetto. Porta via: tutto ciò che rende incoerente il tuo JSON genererà un errore. Suggerimento bonus: non fidarti di jsonviewer.stack.hu Usa qualcosa come jsonlint
Aman Alam

Risposte:


68

Potrebbe essere la codifica dei caratteri speciali. Potresti chiedere a json_last_error () di ottenere informazioni certe.

Aggiornamento: il problema è risolto, guarda il paragrafo "Soluzione" nella domanda.


Uso i caratteri speciali da quando ho avviato l'applicazione e prima non c'erano problemi. A livello locale, la decodifica JSON funziona perfettamente. Sul mio server, non è così. E non posso chiamare json_last_error()perché è PHP 5.2.9. Questa funzione appare su PHP 5.3.0.
Joel A. Villarreal Bertoldi

1
No, dovrebbe funzionare. Non posso fare altri test in questo momento, se ci arrivo più tardi posterò qui. Ci sono anche alcuni suggerimenti nelle note fornite dagli utenti: de.php.net/json_decode forse qualcosa aiuta.
Pekka

1
Per me, su PHP 5.3, funziona bene quando il testo è codificato in UTF-8. Ma se passo prima il testo utf8_decode(), json_decode()fallisce silenziosamente.
Matteo

1
@Pekka Alla ricerca di risposte su Google, sono tornato a SO: stackoverflow.com/questions/689185/json-decode-returns-null-php . Il mio file JSON aveva la sequenza UTF BOM (alcuni caratteri binari che non dovrebbero essere presenti), quindi interrompendo la struttura JSON. Sono andato in Hex Editor, ho cancellato i byte. È tornato tutto normale. Perché è successo? Perché ho modificato il file utilizzando il Blocco note di Micro $ oft Windows. Pessima idea!
Joel A. Villarreal Bertoldi

2
Questo dovrebbe essere segnalato come un bug alla gente di PHP. Se la distinta base era UTF8 valida, non dovrebbe soffocarla silenziosamente.
jmucchiello

86

Questo ha funzionato per me

json_decode( preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $json_string), true );

2
L'ho usato e ho ottenuto l'array, ma anche i caratteri specifici della mia lingua (ş, ç, ö, ..) sono stati eliminati.
zkanoca

5
Questo non è corretto se i dati json sono codificati in UTF-8 (o qualsiasi codifica UTF immagino). Rimuoverà i dati validi con codifica UTF-8. Probabilmente funzionerà fintanto che il file contiene solo la lingua inglese, ma è sempre un'ipotesi rischiosa. Non lo userei.
DaedalusAlpha

Con questo funziona ma senza no, anche se le due corde sono identiche, mi manca qualcosa?
Rudie Visser

funziona! ma perché? la stringa che ho provato a decodificare non conteneva caratteri speciali
Tobias Gassmann

Eccezionale. Ha funzionato per me. :)
Sohil

31

Potresti provarci.

json_decode(stripslashes($_POST['data']))

Ho chiamato accidentalmente stripslashes()due volte, il che ha rimosso le barre essenziali e ha causato una stringa JSON non valida. Questa risposta mi ha aiutato a individuare l'errore
Philipp

22

Se controlli la richiesta in chrome vedrai che il JSON è testo, quindi è stato aggiunto del codice vuoto al JSON.

Puoi cancellarlo usando

$k=preg_replace('/\s+/', '',$k);

Quindi puoi usare:

json_decode($k)

print_r mostrerà quindi l'array.


Grazie per questo - spero che trovi il tuo inglese mancante.
Dean_Wilson

Amico, sei una leggenda, ci ho litigato per tutto il giorno.
Sboniso Marcus Nzimande

L'ha fatto per me !! Una semplice modifica che ho apportato è l'aggiunta di uno spazio nella sostituzione, lo sto usando e sembra sostituire anche il mio spazio. funziona bene ora. $k=preg_replace('/\s+/', ' ',$k);
Kash

Il problema è che questo rimuove ogni singolo spazio, rendendo tutto il testo inglese bloccato insieme, non è vero?
CodeGuru

14

Ho avuto lo stesso problema e l'ho risolto semplicemente sostituendo il carattere di citazione prima della decodifica.

$json = str_replace('"', '"', $json);
$object = json_decode($json);

Il mio valore JSON è stato generato dalla funzione JSON.stringify.


In questo caso è possibile che venga utilizzata la funzione htmlspecialchars e il JSON non può più essere analizzato. Per invertirlo c'è la funzione "htmlspecialchars_decode" invece di sostituire manualmente & quot;
Davy

11

Forse alcuni personaggi nascosti stanno scherzando con il tuo json, prova questo:

$json = utf8_encode($yourString);
$data = json_decode($json);

Dopo aver provato tutte le soluzioni sopra, questa finalmente ha funzionato per me. Grazie mille !!
Anis R.

7
$k=preg_replace('/\s+/', '',$k); 

l'ha fatto per me. E sì, test su Chrome. Grazie a user2254008


4

Ho solo pensato di aggiungere questo, poiché oggi mi sono imbattuto in questo problema. Se è presente una spaziatura di stringa attorno alla stringa JSON, json_decode restituirà NULL.

Se stai estraendo il JSON da una fonte diversa da una variabile PHP, sarebbe saggio prima "tagliarlo":

$jsonData = trim($jsonData);

4

questo ti aiuta a capire qual è il tipo di errore

<?php
// A valid json string
$json[] = '{"Organization": "PHP Documentation Team"}';

// An invalid json string which will cause an syntax 
// error, in this case we used ' instead of " for quotation
$json[] = "{'Organization': 'PHP Documentation Team'}";


foreach ($json as $string) {
    echo 'Decoding: ' . $string;
    json_decode($string);

    switch (json_last_error()) {
        case JSON_ERROR_NONE:
            echo ' - No errors';
        break;
        case JSON_ERROR_DEPTH:
            echo ' - Maximum stack depth exceeded';
        break;
        case JSON_ERROR_STATE_MISMATCH:
            echo ' - Underflow or the modes mismatch';
        break;
        case JSON_ERROR_CTRL_CHAR:
            echo ' - Unexpected control character found';
        break;
        case JSON_ERROR_SYNTAX:
            echo ' - Syntax error, malformed JSON';
        break;
        case JSON_ERROR_UTF8:
            echo ' - Malformed UTF-8 characters, possibly incorrectly encoded';
        break;
        default:
            echo ' - Unknown error';
        break;
    }

    echo PHP_EOL;
}
?>

2

Risparmia solo una volta. Ho impiegato 3 ore per scoprire che si trattava solo di un problema di codifica html. Prova questo

if(get_magic_quotes_gpc()){
   $param = stripslashes($row['your column name']);
}else{
  $param = $row['your column name'];
}

$param = json_decode(html_entity_decode($param),true);
$json_errors = array(
JSON_ERROR_NONE => 'No error has occurred',
JSON_ERROR_DEPTH => 'The maximum stack depth has been exceeded',
JSON_ERROR_CTRL_CHAR => 'Control character error, possibly incorrectly encoded',
JSON_ERROR_SYNTAX => 'Syntax error',
);
echo 'Last error : ', $json_errors[json_last_error()], PHP_EOL, PHP_EOL;
print_r($param);

1

Come affermato da Jürgen Math utilizzando il metodo preg_replace elencato da user2254008, l'ho risolto anche per me.

Questo non è limitato a Chrome, sembra essere un problema di conversione del set di caratteri (almeno nel mio caso, Unicode -> UTF8) Questo ha risolto tutti i problemi che stavo avendo.

Come nodo futuro, l'oggetto JSON che stavo decodificando proveniva dalla funzione json.dumps di Python. Ciò a sua volta ha causato la diffusione di altri dati antigienici sebbene fosse facilmente gestibile.


1

Se stai ricevendo json dal database, metti

mysqli_set_charset($con, "utf8");

dopo aver definito il collegamento di connessione $ con


Grazie TomoMiha. Questo è esattamente ciò che si adatta a tutti i miei problemi con MySQL contenente caratteri speciali e quando convertito da json_decode, quel particolare campo è stato restituito = null ....
KLL


1

Nel mio caso, è a causa della virgoletta singola nella stringa JSON.

Il formato JSON accetta solo virgolette doppie per chiavi e valori stringa.

Esempio:

$jsonString = '{\'hello\': \'PHP\'}'; // valid value should be '{"hello": "PHP"}'
$json = json_decode($jsonString);
print $json; // null

Mi sono confuso a causa della sintassi Javascript. In Javascript, ovviamente, possiamo fare in questo modo:

let json = {
    hello: 'PHP' // no quote for key, single quote for string value
}

// OR:
json = {
    'hello': 'PHP' // single quote for key and value
}

ma in seguito, quando converti quegli oggetti in una stringa JSON:

JSON.stringify(json); // "{"hello":"PHP"}"

0

Ho risolto questo problema stampando il JSON e quindi controllando l'origine della pagina (CTRL / CMD + U):

print_r(file_get_contents($url));

Si è scoperto che c'era un <pre>tag finale .


0

dovresti assicurarti di questi punti

1. la tua stringa json non ha caratteri sconosciuti

2. stringa json può essere visualizzata dal visualizzatore json online (puoi cercare su google come visualizzatore online o parser per json) dovrebbe essere visualizzata senza errori

3. la tua stringa non ha entità html dovrebbe essere testo / stringa semplice

per la spiegazione del punto 3

$html_product_sizes_json=htmlentities($html);
    $ProductSizesArr = json_decode($html_product_sizes_json,true);

a (rimuovere la funzione htmlentities ())

$html_product_sizes_json=$html;
    $ProductSizesArr = json_decode($html_product_sizes_json,true);

0

Per me, ho dovuto disattivare error_reporting , per far funzionare correttamente json_decode (). Sembra strano, ma nel mio caso è vero. Perché c'è un avviso stampato tra la stringa JSON che sto cercando di decodificare.


0

La cosa più importante da ricordare, quando si ottiene un risultato NULL da dati JSON valido è utilizzare il seguente comando:

json_last_error_msg();

Vale a dire.

var_dump(json_last_error_msg());
string(53) "Control character error, possibly incorrectly encoded"

Quindi risolvi il problema con:

$new_json = preg_replace('/[[:cntrl:]]/', '', $json);

0

Quindi, html_entity_decode () ha funzionato per me. Per favore prova questo.

$input = file_get_contents("php://input");
$input = html_entity_decode($input);
$event_json = json_decode($input,true);

-5
<?php 
$json_url = "http://api.testmagazine.com/test.php?type=menu";
$json = file_get_contents($json_url);
$json=str_replace('},

]',"}

]",$json);
$data = json_decode($json);

echo "<pre>";
print_r($data);
echo "</pre>";
?>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.