API-Debugging mal schnell: Warum gibt dein JSON einen Fehler zurück?
\n\nHast du schon einmal um drei Uhr morgens vor einem leeren Postman-Bildschirm gesessen und dich gefragt: „Warum liefert mein PHP-Skript HTML statt JSON?“? Wenn ja, bist du nicht allein. Das Thema Returning JSON from a PHP Script hat auf Stack Overflow Zehntausende von Aufrufen – und das aus gutem Grund. Fast jeder zweite angehende Backend-Entwickler macht dieselben Fehler: vergessene Header, überflüssige Ausgaben, falscher Content-Type.
\n\nIn diesem Artikel kopieren wir nicht einfach eine Antwort aus dem Forum. Wir analysieren, wie man JSON aus PHP korrekt, schnell und ohne Überraschungen zurückgibt. Du erfährst, warum exit(json_encode($data)) dich in die Irre führen kann, wie du Millisekunden bei der Serialisierung sparst und was zu tun ist, wenn JSON plötzlich „kaputt“ ist.
Bereit? Los geht's.
\n\nAnatomie einer korrekten JSON-Antwort
\n\nFangen wir mit den Grundlagen an. So solltest du es nicht machen:
\n\n<?php\n$data = ['status' => 'ok', 'message' => 'Hallo!'];\necho json_encode($data);\n?>\n\nWarum ist das schlecht? Erstens fehlt der Content-Type-Header. Der Browser oder Client könnte die Antwort als HTML oder Text interpretieren. Zweitens: Wenn vorher im Code ein Leerzeichen, ein echo oder eine Warnung war, ist das JSON defekt.
Die korrekte minimale Vorlage sieht so aus:
\n\n<?php\nheader('Content-Type: application/json; charset=utf-8');\n$data = ['status' => 'ok', 'message' => 'Hallo!'];\necho json_encode($data, JSON_UNESCAPED_UNICODE);\nexit;\n?>\n\nBeachte JSON_UNESCAPED_UNICODE – es erhält Umlaute und Sonderzeichen lesbar, anstatt sie in \\u00E4hnliche Sequenzen zu verwandeln. Und exit ist eine Absicherung gegen versehentliche Ausgaben nach der Antwort.
Header: Nicht nur Content-Type
\n\nFür die Optimierung der JSON-Performance füge noch ein paar Header hinzu:
\n\nheader('Content-Type: application/json; charset=utf-8');\nheader('X-Content-Type-Options: nosniff');\nheader('Cache-Control: no-cache, must-revalidate');\n\nX-Content-Type-Options: nosniff verhindert, dass der Browser den Inhaltstyp „errät“ – das ist Sicherheit. Und Cache-Control ist nützlich für dynamische Daten, damit der Client keine veraltete Antwort zwischenspeichert.
Fehlerbehandlung: Wenn json_encode fehlschlägt
\n\nDie Funktion json_encode gibt bei einem Fehler false zurück. Und hier wird es spannend. Wenn du einfach echo json_encode($data) machst und als Antwort einen leeren String erhältst, ist der Client verwirrt.
Überprüfe immer das Ergebnis:
\n\n$json = json_encode($data, JSON_UNESCAPED_UNICODE);\nif ($json === false) {\n http_response_code(500);\n echo json_encode(['error' => 'JSON-Kodierung fehlgeschlagen: ' . json_last_error_msg()]);\n exit;\n}\necho $json;\nexit;\n\nÜbrigens: json_last_error_msg() liefert eine verständliche Meldung wie „Malformed UTF-8 characters“ oder „Inf and NaN cannot be JSON encoded“. Das spart stundenlanges Debuggen.
Tief verschachtelte Daten und Rekursion
\n\nEin weiteres Problem sind zyklische Referenzen in Objekten. Wenn du ein Objekt mit gegenseitigen Verweisen übergibst, wirft json_encode einen Fehler. Lösung: Verwende JSON_PARTIAL_OUTPUT_ON_ERROR oder wandle das Objekt vorher in ein Array um.
$json = json_encode($complexObject, JSON_UNESCAPED_UNICODE | JSON_PARTIAL_OUTPUT_ON_ERROR);\n\nSei aber vorsichtig: Die partielle Ausgabe kann unvollständig sein. Es ist besser, die Datenstruktur zu reparieren.
\n\nPerformance-Optimierung von JSON in PHP
\n\nKommen wir zum spannendsten Teil – wie du das Zurückgeben von JSON aus PHP beschleunigen kannst.
\n\n1. Caching von serialisiertem JSON
\n\nWenn sich Daten selten ändern (Nachschlagewerke, Konfigurationen, Städtelisten), serialisiere sie nicht jedes Mal neu. Speichere das fertige JSON in einer Datei, in Memcached