Navigation
 Startseite
 Fachbücher
 Anzeigenmarkt
 Forum
 Webmaster News
 Script Newsletter
 Kontakt
 Script Installation
 Php
 Php Tutorials
 Lernpfade
 Webhoster Vergleich
 Impressum

Community-Bereich
 kostenlos Registrieren
 Anmelden
 Benutzerliste

Script Datenbank
 Script Archiv
 Script Top 20
 Screenshots
 Testberichte

Suche
 

Unsere Php Scripts
 Counter Script
 Umfrage Script
 Bilder Upload Script
 Terminverwaltung
 Simple PHP Forum
 RSS Grabber

Tools und Generatoren
 .htpasswd Generator
 md5 Generator
 base64 Generator
 Markdown to HTML
 Colorpicker
 Unix timestamp Tool
 Unit Test Generator
 TLD Liste
 Webkatalog‑Verzeichnis

Artfiles.de
Bietet Serviceorientierte...
https://www.Artfiles.de
Hosterplus.de
Bekommen Sie Speicherplatz (Webspace), Domains...
https://www.Hosterplus.de
 
 
 

PHP json_decode(): JSON sicher in PHP-Daten umwandeln

Sie befinden sich: Home > Php Tutorial > PHP json_decode(): JSON sic...

PHP json_decode(): JSON sicher in PHP-Daten umwandeln
Eintrag am:
07.08.2026
Hits / Besucher:
14
Sprache:
  Deutsch
Tutorial Art:
eigenes
Eingetragen von:
Merkliste:
 
Beschreibung

Eine API antwortet, die Daten sehen im Browser gut aus, und im Skript kommt trotzdem nichts an. Oder $daten['name'] löst einen Fehler aus, obwohl das Feld sichtbar im JSON steht. Beide Fälle haben mit PHP json_decode zu tun, genauer mit zwei Eigenheiten der Funktion, die man einmal verstanden haben muss.

Illustration zum Tutorial: PHP json_decode(): JSON sicher in PHP-Daten umwandeln

Die erste betrifft den zweiten Parameter und ist schnell erledigt.

JSON einlesen mit PHP json_decode

Ohne zweiten Parameter liefert PHP json_decode ein Objekt der Klasse stdClass. Mit true liefert die Funktion ein assoziatives Array. Der Zugriff unterscheidet sich entsprechend.

<?php

$json = '{"name":"Kaffeemuehle","preis":49.90,"tags":["kueche","muehle"]}';

/* Ohne zweiten Parameter: stdClass */
$objekt = json_decode($json);
echo $objekt->name; /* Kaffeemuehle */
echo $objekt->tags[0]; /* kueche */

/* Mit true: assoziatives Array */
$array = json_decode($json, true);
echo $array['name']; /* Kaffeemuehle */
echo $array['tags'][0]; /* kueche */

Beachte den Unterschied bei tags: JSON-Arrays werden in beiden Fällen zu PHP-Arrays. Nur JSON-Objekte, also die Blöcke in geschweiften Klammern, hängen vom zweiten Parameter ab. In einer verschachtelten Struktur mischen sich deshalb Pfeil- und Klammerzugriff, wenn du ohne true arbeitest.

stdClass oder assoziatives Array?

Beide Varianten funktionieren. Die Wahl sollte trotzdem nicht dem Zufall überlassen bleiben, weil gemischte Verwendung im selben Projekt regelmässig zu Typfehlern beim Übergeben zwischen Funktionen führt.

Sprich für Array (mit true) Objekt (Standard)
Schlüssel stehen erst zur Laufzeit fest ja, $d[$name] ist selbstverständlich möglich, aber umständlicher
Array-Funktionen wie array_column() direkt nutzbar nur teilweise
Feste, bekannte Struktur geht auch ja, liest sich flüssiger
Schlüssel mit Bindestrich oder Leerzeichen unproblematisch nur über $o->{'mein-feld'}

Die Empfehlung für neue Projekte lautet: true setzen und projektweit dabei bleiben. Der letzte Punkt der Tabelle gibt dabei den Ausschlag, denn Feldnamen mit Bindestrich kommen in fremden APIs häufig vor und machen den Objektzugriff sofort unhandlich.

Warum null zweideutig ist

Jetzt zur zweiten Eigenheit, und die ist die wichtigere. PHP json_decode liefert bei einem Fehler null zurück. Das Problem: null ist auch ein völlig gültiges Ergebnis, nämlich für die Eingabe "null". Am Rückgabewert allein lässt sich beides nicht unterscheiden.

<?php

var_dump(json_decode('null')); /* NULL, korrektes Ergebnis */
var_dump(json_decode('{kaputt')); /* NULL, Syntaxfehler */

/* Beide sehen gleich aus. Der Unterschied steht woanders: */
json_decode('null');
echo json_last_error(); /* 0, kein Fehler */

json_decode('{kaputt');
echo json_last_error(); /* 4 */
echo json_last_error_msg(); /* Syntax error */

Genau hier entstehen die stillen Ausfälle. Ein Skript verarbeitet monatelang Webhook-Daten, bis der Absender einmal etwas Ungültiges schickt. Ohne Prüfung läuft der Code mit null weiter, und der eigentliche Fehler taucht drei Funktionen später als unverständliche Meldung auf.

Ein Hinweis zu json_last_error(): die Funktion bezieht sich immer auf den zuletzt erfolgten Aufruf. Wer zwischen dem Dekodieren und der Fehlerprüfung ein zweites Mal dekodiert, prüft den falschen Vorgang.

Fehler abfangen mit JSON_THROW_ON_ERROR

Seit PHP 7.3 gibt es einen Weg, der die ganze Fehlerabfrage überflüssig macht. Das Flag JSON_THROW_ON_ERROR lässt PHP json_decode eine JsonException werfen, statt still null zu liefern.

<?php

try {
$daten = json_decode(
$eingabe,
true,
512,
JSON_THROW_ON_ERROR
);
} catch (JsonException $e) {
error_log('JSON ungueltig: ' . $e->getMessage());
http_response_code(400);
exit('Ungueltige Daten empfangen.');
}

/* Ab hier ist $daten garantiert dekodiert. */

Der Gewinn liegt nicht nur in der kürzeren Schreibweise. Eine Exception lässt sich nicht versehentlich übersehen, ein Rückgabewert schon. Für neuen Code ist das die richtige Variante, und die alte Fehlerabfrage bleibt nur dort nötig, wo PHP 7.2 oder älter unterstützt werden muss.

Beim Einlesen aus einer Datei kommt eine zweite Fehlerquelle dazu, die gern vergessen wird.

<?php

$pfad = __DIR__ . '/konfiguration.json';

$roh = file_get_contents($pfad);
if ($roh === false) {
throw new RuntimeException('Datei nicht lesbar: ' . $pfad);
}

$konfig = json_decode($roh, true, 512, JSON_THROW_ON_ERROR);
echo $konfig['datenbank']['host'];

Ohne die Prüfung auf false landet bei einer fehlenden Datei ein leerer String in der Funktion, und der ist kein gültiges JSON. Die Meldung lautet dann "Syntax error", was in die Irre führt: das eigentliche Problem war der Dateipfad.

Der folgende Ablauf zeigt beide Wege der Fehlerbehandlung nebeneinander.

flowchart TD
    A[JSON-String] --> B[json_decode aufrufen]
    B --> C{Flag gesetzt?}
    C -->|JSON_THROW_ON_ERROR| D[Exception bei Fehler]
    C -->|Ohne Flag| E{Rueckgabe null?}
    E -->|Ja| F[json_last_error pruefen]
    E -->|Nein| G[Daten vorhanden]
    D --> G
    G --> H[Struktur und Felder pruefen]

Verschachtelungstiefe mit dem depth-Parameter

Der dritte Parameter von PHP json_decode begrenzt, wie tief verschachtelt die Struktur sein darf. Der Standardwert ist 512, und wer ihn erreicht, bekommt eine Meldung, die ohne Vorwissen rätselhaft bleibt.

<?php

/* Sieben Ebenen tief, Limit auf 3 gesetzt */
$tief = '{"a":{"b":{"c":{"d":{"e":{"f":{"g":1}}}}}}}';

var_dump(json_decode($tief, true, 3));
echo json_last_error_msg(); /* Maximum stack depth exceeded */

var_dump(json_decode($tief, true, 20) !== null); /* bool(true) */

In der Praxis reichen 512 Ebenen fast immer aus. Wer den Wert erhöhen muss, sollte kurz innehalten: bei Daten aus fremder Quelle ist das Limit auch ein Schutz. Eine künstlich tief verschachtelte Eingabe kann sonst gezielt Speicher belegen.

Grosse Ganzzahlen und der Präzisionsverlust

Dieses Fehlerbild bleibt oft lange unbemerkt, weil nichts abbricht. Die Zahlen sind einfach falsch.

<?php

$json = '{"id":12345678901234567890}';

$standard = json_decode($json, true);
var_dump($standard['id']);
/* float(1.2345678901235E+19), Genauigkeit verloren */

$sicher = json_decode($json, true, 512, JSON_BIGINT_AS_STRING);
var_dump($sicher['id']);
/* string(20) "12345678901234567890" */

Sobald eine Ganzzahl grösser ist als PHP_INT_MAX, wandelt PHP json_decode sie in einen Float um, und Floats speichern nur eine begrenzte Anzahl signifikanter Stellen. Bei einer Bestell- oder Transaktionsnummer bedeutet das, dass die letzten Stellen verfälscht werden. Mit JSON_BIGINT_AS_STRING kommen solche Werte als String an und bleiben unverändert. Betroffen sind vor allem APIs, die IDs als Zahl statt als String liefern, was bei Snowflake-IDs und Zeitstempeln in Mikrosekunden häufig vorkommt.

JSON verlangt UTF-8

Die Spezifikation kennt nur UTF-8. Daten aus einem alten System in Latin-1 führen deshalb zu einem Fehler, dessen Meldung nicht auf die Ursache zeigt.

<?php

/* Ein Latin-1-kodierter Umlaut im JSON */
$latin = mb_convert_encoding('{"ort":"München"}', 'ISO-8859-1', 'UTF-8');

var_dump(json_decode($latin, true)); /* NULL */
echo json_last_error_msg(); /* Malformed UTF-8 characters ... */

/* Loesung: vorher konvertieren */
$utf8 = mb_convert_encoding($latin, 'UTF-8', 'ISO-8859-1');
var_dump(json_decode($utf8, true)); /* array mit korrektem Wert */

Prüfen lässt sich das mit mb_check_encoding($roh, 'UTF-8'), bevor überhaupt dekodiert wird. Das erspart die Suche nach einem vermeintlichen Syntaxfehler.

Gültiges JSON heisst nicht erwartete Struktur

Ein erfolgreicher Aufruf sagt nur, dass die Syntax stimmte. Ob die Felder da sind, mit denen dein Code rechnet, ist eine andere Frage, und die beantwortet PHP json_decode nicht.

<?php

$daten = json_decode($eingabe, true, 512, JSON_THROW_ON_ERROR);

if (!is_array($daten)) {
throw new UnexpectedValueException('Objekt erwartet.');
}

foreach (['name', 'preis'] as $pflichtfeld) {
if (!array_key_exists($pflichtfeld, $daten)) {
throw new UnexpectedValueException(
'Feld fehlt: ' . $pflichtfeld
);
}
}

if (!is_numeric($daten['preis'])) {
throw new UnexpectedValueException('Preis muss eine Zahl sein.');
}

Die Prüfung auf is_array() am Anfang ist kein überflüssiger Schritt. Auch 42 und "text" sind gültiges JSON, und beides würde bei einem Feldzugriff sonst in einer schwer zu deutenden Meldung enden.

Wer nur wissen will, ob ein String gültiges JSON ist, ohne das Ergebnis zu brauchen, findet seit PHP 8.3 eine sparsamere Lösung im Tutorial zu PHP json_validate(). Die Gegenrichtung, also das Erzeugen von JSON aus PHP-Daten, behandelt das Tutorial zu PHP json_encode. Und wie eine Schnittstelle aussieht, die solche Daten entgegennimmt, zeigt PHP REST API erstellen.

Fazit zu PHP json_decode

Zwei Entscheidungen prägen jeden Aufruf von PHP json_decode. Die erste ist der zweite Parameter: true liefert Arrays und ist für die meisten Projekte die praktischere Wahl. Die zweite ist die Fehlerbehandlung, und dort führt in neuem Code kein Weg an JSON_THROW_ON_ERROR vorbei.

Drei Parameter lösen die Fehlerbilder, die sonst Stunden kosten. depth bei tief verschachtelten Daten, JSON_BIGINT_AS_STRING bei langen IDs, und eine Encoding-Prüfung bei Daten aus Altsystemen. Was danach bleibt, ist die Prüfung der Struktur, und die musst du selbst schreiben.

 

Tags:

 

 

Kommentare (0)

Noch keine Kommentare. Sei der Erste!

Melde dich an, um einen Kommentar zu schreiben.
Bücherregal mit drei Büchern: 'PHP 4 - Grundlagen und Profiwissen' von Hanser Verlag, 'Webdesign in a Nutshell' von O'Reilly Verlag, und 'Webgestaltung' von Galileo Computing.