PHP json_decode () gibt NULL mit gültigem JSON zurück?

103

Ich habe dieses JSON-Objekt in einer Nur-Text-Datei gespeichert:

{
    "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"
    }
}

Wenn ich versuche, es mit zu dekodieren json_decode(), wird NULL zurückgegeben. Warum? Die Datei ist lesbar (ich habe versucht, sie wiederzugeben, file_get_contents()und es hat einwandfrei funktioniert).

Ich habe JSON gegen http://jsonlint.com/ getestet und es ist vollkommen gültig.

Was ist hier los?

Lösung

Auf der Suche nach Antworten bei Google bin ich zu SO zurückgekehrt: json_decode gibt nach dem Webservice-Aufruf NULL zurück . Meine JSON-Datei hatte die UTF-Stücklistenfolge (einige Binärzeichen, die nicht vorhanden sein sollten), wodurch die JSON-Struktur beschädigt wurde. Ging zum Hex-Editor und löschte die Bytes. Alles ist wieder normal. Warum ist das passiert? Weil ich die Datei mit dem Microsoft Windows-Editor bearbeitet habe. Schreckliche Idee!

Joel A. Villarreal Bertoldi
quelle
5
Arbeiten mit PHP 5.2.9; daher kann ich nicht verwenden json_last_error().
Joel A. Villarreal Bertoldi
1
Beachten Sie auch, dass dies bei anderen ungültigen Zeichen in der Mitte der Datei passieren kann. Ich hatte gerade json_decode (), der null zurückgab, weil die Zeichenfolge einen dieser speziellen Striche enthielt, die wahrscheinlich aus MS Word eingefügt und dann möglicherweise falsch codiert wurden. Öffnen Sie die JSON-Datei (die ich in Notepad ++ verwendet habe), ändern Sie die Codierung (ohne sie zu konvertieren) und speichern Sie sie als Kopie, um potenzielle Problemzeichen zu identifizieren. Dann unterscheiden sich die beiden Dateien (ich habe WinMerge verwendet).
LinusR
(Windows Notepad-Problem) Bitte konsultieren Sie dies, ich habe das Problem auch geteilt und es wurde behoben: stackoverflow.com/questions/10290849/…
Felix Aballi
Für mich war es nichts Besonderes, nur ein zusätzliches Komma am Ende eines Objektelements. Take away: Alles, was Ihren JSON inkonsistent macht, wird einen Fehler auslösen. Bonus-Tipp: Vertrauen Sie nicht jsonviewer.stack.hu Verwenden Sie so etwas wie jsonlint
Aman Alam

Antworten:

68

Es könnte die Kodierung der Sonderzeichen sein. Sie können json_last_error () bitten , bestimmte Informationen zu erhalten.

Update: Das Problem ist behoben. Lesen Sie den Abschnitt "Lösung" in der Frage.

Pekka
quelle
Ich habe die Sonderzeichen verwendet, seit ich die Anwendung gestartet habe, und es gab vorher keine Probleme. Vor Ort funktioniert die JSON-Dekodierung einwandfrei. Auf meinem Server ist dies nicht der Fall. Und ich kann nicht anrufen, json_last_error()weil es PHP 5.2.9 ist. Diese Funktion erscheint in PHP 5.3.0.
Joel A. Villarreal Bertoldi
1
Nein, das sollte funktionieren. Ich kann momentan keine weiteren Tests durchführen. Wenn ich später dazu komme, werde ich hier posten. Es gibt auch ein paar Hinweise in den vom Benutzer bereitgestellten Notizen: de.php.net/json_decode Vielleicht hilft etwas.
Pekka
1
Unter PHP 5.3 funktioniert es für mich einwandfrei, wenn der Text in UTF-8 codiert ist. Aber wenn ich den Text utf8_decode()zuerst weitergebe, json_decode()schlägt dies stillschweigend fehl.
Matthew
1
@Pekka Auf der Suche nach Antworten bei Google bin ich zu SO zurückgekehrt: stackoverflow.com/questions/689185/json-decode-returns-null-php . Meine JSON-Datei hatte die UTF-Stücklistenfolge (einige Binärzeichen, die nicht vorhanden sein sollten), wodurch die JSON-Struktur beschädigt wurde. Ging zum Hex-Editor und löschte die Bytes. Alles ist wieder normal. Warum ist das passiert? Weil ich die Datei mit dem Windows-Editor von Micro $ of Windows bearbeitet habe. Schreckliche Idee!
Joel A. Villarreal Bertoldi
2
Dies sollte den PHP-Leuten als Fehler gemeldet werden. Wenn die Stückliste UTF8 gültig war, sollte sie nicht stillschweigend daran ersticken.
Jmucchiello
85

Das hat bei mir funktioniert

json_decode( preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $json_string), true );
Dunith Dhanushka
quelle
2
Ich habe dies verwendet und das Array erhalten, aber meine sprachspezifischen Zeichen (ş, ç, ö, ..) wurden ebenfalls gelöscht.
Zkanoca
5
Dies ist nicht korrekt, wenn die JSON-Daten UTF-8-codiert sind (oder eine UTF-Codierung, denke ich). Es werden gültige UTF-8-codierte Daten entfernt. Es wird wahrscheinlich funktionieren, solange die Datei nur die englische Sprache enthält, aber das ist immer eine riskante Annahme. Ich würde das nicht benutzen.
DaedalusAlpha
Damit funktioniert es, aber ohne es nicht, obwohl die beiden Saiten identisch sind, fehlt mir etwas?
Rudie Visser
es funktioniert! aber wieso? Die Zeichenfolge, die ich zu dekodieren versuchte, enthielt keine speziellen Zeichen
Tobias Gassmann,
Genial. Hat für mich gearbeitet. :)
Sohil
30

Sie könnten es versuchen.

json_decode(stripslashes($_POST['data']))
Gabriel Castillo Prada
quelle
22

Wenn Sie die Anforderung in Chrome überprüfen, werden Sie feststellen, dass es sich bei dem JSON um Text handelt. Daher wurde dem JSON ein leerer Code hinzugefügt.

Sie können es mit löschen

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

Dann können Sie verwenden:

json_decode($k)

print_r zeigt dann das Array.

user2254008
quelle
Vielen Dank dafür - ich hoffe, Sie finden Ihr fehlendes Englisch.
Dean_Wilson
Mann, du bist eine Legende, habe den ganzen Tag damit rumgespielt.
Sboniso Marcus Nzimande
Hab es für mich gemacht !! Eine einfache Änderung, die ich vorgenommen habe, ist das Hinzufügen eines Leerzeichens im Ersetzungsmodus. Ich verwende dies und es scheint auch mein Leerzeichen zu ersetzen. funktioniert jetzt gut. $k=preg_replace('/\s+/', ' ',$k);
Kash
Das Problem ist, dass dadurch jedes einzelne Leerzeichen entfernt wird und der englische Text zusammenklebt, nicht wahr?
CodeGuru
14

Ich hatte das gleiche Problem und löste es einfach, indem ich das Anführungszeichen vor dem Dekodieren ersetzte.

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

Mein JSON-Wert wurde von der Funktion JSON.stringify generiert.

Yapp Ka Howe
quelle
In diesem Fall wird möglicherweise die Funktion htmlspecialchars verwendet und der JSON kann nicht mehr analysiert werden. Um es umzukehren, gibt es die Funktion "htmlspecialchars_decode", anstatt & quot;
Davy
11

Vielleicht spielen einige versteckte Charaktere mit Ihrem JSON. Versuchen Sie Folgendes:

$json = utf8_encode($yourString);
$data = json_decode($json);
Albert Abdonor
quelle
Nachdem ich alle oben genannten Lösungen ausprobiert hatte, funktionierte diese endlich für mich. Danke vielmals!!
Anis R.
7
$k=preg_replace('/\s+/', '',$k); 

habe es für mich getan. Und ja, auf Chrome testen. Danke an user2254008

Jürgen Math
quelle
4

Ich dachte nur, ich würde das hinzufügen, als ich heute auf dieses Problem stieß. Wenn Ihre JSON-Zeichenfolge von Zeichenfolgen aufgefüllt wird, gibt json_decode NULL zurück.

Wenn Sie den JSON aus einer anderen Quelle als einer PHP-Variablen ziehen, ist es ratsam, ihn zuerst zu "trimmen":

$jsonData = trim($jsonData);
Phil LaNasa
quelle
4

Dies hilft Ihnen zu verstehen, welche Art von Fehler vorliegt

<?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;
}
?>
Enrico Tempesti
quelle
2

Sparen Sie einfach einmal. Ich habe 3 Stunden damit verbracht herauszufinden, dass es sich nur um ein Problem mit der HTML-Codierung handelt. Versuche dies

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);
Samuel Kwame Antwi
quelle
1

Wie von Jürgen Math mit der von user2254008 aufgelisteten preg_replace-Methode angegeben, wurde dies auch für mich behoben.

Dies ist nicht auf Chrome beschränkt, es scheint sich um ein Problem mit der Zeichensatzkonvertierung zu handeln (zumindest in meinem Fall Unicode -> UTF8). Dadurch wurden alle Probleme behoben, die ich hatte.

Als zukünftiger Knoten stammte das JSON-Objekt, das ich dekodierte, aus Pythons Funktion json.dumps. Dies wiederum führte dazu, dass einige andere unhygienische Daten weitergegeben wurden, obwohl sie leicht zu verarbeiten waren.

Destreyf
quelle
1

Wenn Sie json aus der Datenbank erhalten, setzen Sie

mysqli_set_charset($con, "utf8");

nach dem Definieren des Verbindungslinks $ con

TomoMiha
quelle
Vielen Dank, TomoMiha. Dies ist genau das, was zu all meinen Problemen mit MySQL passt, das Sonderzeichen enthält, und als es von json_decode konvertiert wurde, wurde dieses bestimmte Feld als = null ausgegeben ....
KLL
1

In meinem Fall liegt dies am einfachen Anführungszeichen in der JSON-Zeichenfolge.

Das JSON-Format akzeptiert nur doppelte Anführungszeichen für Schlüssel und Zeichenfolgenwerte.

Beispiel:

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

Ich habe dies wegen der Javascript-Syntax verwirrt. In Javascript können wir natürlich Folgendes tun:

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

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

aber später, wenn diese Objekte in eine JSON-Zeichenfolge konvertiert werden:

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

Ich habe dieses Problem gelöst, indem ich den JSON gedruckt und dann die Seitenquelle überprüft habe (STRG / CMD + U):

print_r(file_get_contents($url));

Es stellte sich heraus, dass es ein nachfolgendes <pre>Tag gab.

Jeffrey Roosendaal
quelle
0

Sie sollten diese Punkte sicherstellen

1. Ihre JSON-Zeichenfolge enthält keine unbekannten Zeichen

2. JSON-Zeichenfolge kann vom Online-JSON-Viewer (Sie können auf Google als Online-Viewer oder Parser nach JSON suchen) angezeigt werden. Sie sollte fehlerfrei angezeigt werden

3. Ihre Zeichenfolge hat keine HTML-Entitäten. Es sollte sich um einfachen Text / Zeichenfolge handeln

zur Erläuterung von Punkt 3

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

to (entferne die Funktion htmlentities ())

$html_product_sizes_json=$html;
    $ProductSizesArr = json_decode($html_product_sizes_json,true);
Hassan Saeed
quelle
0

Für mich musste ich die Fehlerberichterstattung deaktivieren , damit json_decode () richtig funktioniert. Es klingt komisch, aber in meinem Fall wahr. Weil zwischen der JSON-Zeichenfolge, die ich zu dekodieren versuche, ein Hinweis gedruckt ist.

Shasi Kanth
quelle
0

Das Wichtigste, das Sie beachten sollten, wenn Sie ein gültiges NULL-Ergebnis aus JSON-Daten erhalten, ist die Verwendung des folgenden Befehls:

json_last_error_msg();

Dh.

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

Sie beheben das dann mit:

$new_json = preg_replace('/[[:cntrl:]]/', '', $json);
Gewähren
quelle
0

Also hat html_entity_decode () für mich funktioniert. Bitte versuchen Sie dies.

$input = file_get_contents("php://input");
$input = html_entity_decode($input);
$event_json = json_decode($input,true);
Suman Deol
quelle
-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>";
?>
user2648057
quelle