Menu

PHP json_decode(): JSON in Arrays oder Objekte umwandeln

json_decode($json, true) macht aus einem JSON-String ein assoziatives PHP-Array; ohne true bekommst du stdClass-Objekte. Hier: verschachtelte Werte, Fehlerbehandlung mit JSON_THROW_ON_ERROR, json_validate() und warum json_decode null liefert.

Diese Seite enthält ausführbare Editoren - bearbeiten, ausführen und Ausgabe sofort sehen.

json_decode($json, true) macht aus einem JSON-String PHP-Werte, mit jedem JSON-Objekt als assoziativem Array. Lass true weg, dann werden JSON-Objekte stattdessen zu stdClass-Objekten, die du mit -> liest. Ungültiges JSON ergibt null.

Ausgabe:

Ada
js
Ada
php
Array
(
    [name] => Ada
    [age] => 36
    [langs] => Array
        (
            [0] => php
            [1] => js
        )

    [admin] => 1
)

JSON-Arrays werden immer zu PHP-Listen, egal welchen Modus du wählst. Die andere Richtung, von PHP zu JSON, ist json_encode().

Assoziatives Array oder Objekt: true vs false

Beide Modi enthalten dieselben Daten; wähl den, der sich in deinem Code besser liest. Arrays funktionieren mit jeder Array-Funktion (array_column, array_map, isset($data['key'])), deshalb übergeben die meisten true. Objekte brauchen die Klammersyntax für Schlüssel, die keine gültigen Eigenschaftsnamen sind, etwa Schlüssel mit Bindestrich oder Zahlen:

Ausgabe:

Ada zero London
Ada zero London
object(stdClass)#2 (1) {
  ["city"]=>
  string(6) "London"
}

Der vierte Parameter nimmt Flags. JSON_OBJECT_AS_ARRAY liefert ebenfalls Arrays, aber nur, solange das zweite Argument null ist (sein Standardwert): json_decode($json, flags: JSON_OBJECT_AS_ARRAY) liefert Arrays, während json_decode($json, false, 512, JSON_OBJECT_AS_ARRAY) weiterhin Objekte liefert.

Über verschachteltes JSON iterieren

API-Antworten sind meist eine Liste von Objekten in einem Objekt. Dekodiere einmal, lauf dann mit foreach durch und verwende ?? für Felder, die fehlen könnten:

Ausgabe:

#1 Ada <ada@example.com> roles: admin, editor
#2 Linus <no email> roles: none
#3 Grace <grace@example.com> roles: editor
Array
(
    [1] => Ada
    [2] => Linus
    [3] => Grace
)

Ungültiges JSON behandeln

json_decode() liefert null für ungültiges JSON, aber null ist auch das korrekte Ergebnis für den JSON-Text null, also verrät null allein nicht, ob es gescheitert ist. json_last_error_msg() nennt den Grund des letzten Aufrufs. Der sauberere Weg ist JSON_THROW_ON_ERROR, das eine JsonException wirft:

Ausgabe:

NULL
Syntax error
NULL
No error
Invalid JSON: Syntax error

Das dritte Argument, 512, ist die maximale Verschachtelungstiefe (der Standard). Mit benannten Argumenten kannst du es überspringen: json_decode($json, true, flags: JSON_THROW_ON_ERROR).

Mit json_validate() prüfen, ob ein String gültiges JSON ist

PHP 8.3 brachte json_validate(). Es antwortet mit true oder false, ohne die dekodierten Arrays aufzubauen, und braucht deshalb weniger Speicher als das Dekodieren, wenn du nur ein Ja oder Nein brauchst, etwa um einen Request-Body früh abzulehnen:

Ausgabe:

'{"a": 1}'    valid
'[1, 2, 3]'   valid
'"text"'      valid
'{a: 1}'      invalid: Syntax error
'{\'a\': 1}'  invalid: Syntax error
''            invalid: Syntax error

Wenn du die Daten sowieso verwendest, lass json_validate() weg und dekodiere mit JSON_THROW_ON_ERROR: Vorher zu validieren parst den String zweimal.

Eine JSON-Datei lesen

Lies die Datei mit file_get_contents() und dekodiere den String. Dieser Block schreibt zuerst settings.json, damit es eine Datei zum Lesen gibt:

Ausgabe:

Theme: dark
Plugins: 2
{
    "theme": "dark",
    "fontSize": 16,
    "plugins": [
        "git",
        "lint"
    ]
}

Warum json_decode null liefert: die üblichen Ursachen

JSON ist strenger als JavaScript und als die Array-Syntax von PHP. Jeder String unten sieht vernünftig aus, und jeder liefert null. Führe es aus, um den Grund für jeden zu sehen, korrigiere dann einen und führe es erneut aus:

Ausgabe:

single quotes    Syntax error
unquoted key     Syntax error
trailing comma   Syntax error
comment          Syntax error
byte order mark  Syntax error
too deep         Maximum stack depth exceeded
float(1.2345678901234567E+19)
string(20) "12345678901234567890"

Eine Byte Order Mark ist in den meisten Editoren unsichtbar und der klassische Grund, warum eine JSON-Datei „gut aussieht“, sich aber nicht dekodieren lässt. Entferne sie vor dem Dekodieren mit $text = preg_replace('/^\xEF\xBB\xBF/', '', $text);.

Häufig gestellte Fragen

Wie wandle ich in PHP JSON in ein Array um?

Übergib true als zweites Argument: json_decode('{"name":"Ada"}', true) liefert ['name' => 'Ada'], also liest du Werte mit $data['name']. Ohne true werden JSON-Objekte zu stdClass-Objekten, und du schreibst $data->name.

Warum liefert json_decode null?

Das JSON ist ungültig (einfache Anführungszeichen, ein Komma am Ende, Schlüssel ohne Anführungszeichen, eine Byte Order Mark), es ist tiefer verschachtelt als das Tiefenlimit, oder das JSON ist wirklich null. Prüfe json_last_error_msg() oder dekodiere mit JSON_THROW_ON_ERROR, um eine JsonException mit dem Grund zu bekommen.

Wie prüfe ich in PHP, ob ein String gültiges JSON ist?

Seit PHP 8.3 liefert json_validate($string) true oder false, ohne den dekodierten Wert aufzubauen. In älteren Versionen dekodierst du und prüfst json_last_error() === JSON_ERROR_NONE.

Wie lese ich in PHP eine JSON-Datei?

Lies die Datei und dekodiere sie dann: $data = json_decode(file_get_contents('data.json'), true, flags: JSON_THROW_ON_ERROR);. file_get_contents() liefert false, wenn die Datei fehlt, also prüfst du das zuerst.

Wie greife ich in PHP auf einen JSON-Schlüssel mit Bindestrich zu?

Dekodiere in ein Array und verwende $data['first-name'], oder bei Objekten geschweifte Klammern: $obj->{'first-name'}. Dieselbe Klammersyntax funktioniert für Schlüssel, die Zahlen sind, etwa $obj->{'0'}.

Illustration der Programmiersprachen bei Coddy

Lerne mit Coddy zu programmieren

LOS GEHT'S