JSON und PHP – das dynamische Duo
Kommentare

JSON decodieren in PHP
Decodieren ist so einfach wie codieren. PHP enthält analog zur json_encode()-Funktion auch eine mit dem Namen json_decode(). Dieser wird ein JSON String übergeben, welcher ohne

JSON decodieren in PHP

Decodieren ist so einfach wie codieren. PHP enthält analog zur json_encode()-Funktion auch eine mit dem Namen json_decode(). Dieser wird ein JSON String übergeben, welcher ohne weitere Parameter ein Objekt vom Typ stdClass zurückgibt. Hier ist ein kurzes Beispiel:

 string(3) "bar" ["cool"]=> string(4) "attr" }
	var_dump($result);

	// Gibt "bar" aus.
	echo $result->foo;

	// Gibt "attr" aus.
	echo $result->cool;
	?>

Wenn stattdessen ein assoziatives Array zurückgegeben werden soll, kann der zweite Parameter auf true gesetzt werden:

 string(3) "bar" ["cool"]=> string(4) "attr" }
	var_dump($result);

	// Gibt "bar" aus.
	echo $result['foo'];

	// Gibt "attr" aus.
	echo $result['cool'];
	?>

Sollte ein potentiell zu tief geschachteltes JSON-Dokument decodiert werden, kann man mit dem Limit Argument eine maximale Parsingtiefe einstellen. Falls diese überschritten wird, gibt die Funktion NULL zurück.


Das letzte Argument funktioniert genau so wie json_encode(), allerdings wird aktuell nur eine Konstante unterstützt (welche es erlaubt, große Integerzahlen in Strings umzuwandeln). Diese funktioniert allerdings erst mit PHP 5.4.

Bis jetzt haben wir uns ausschließlich mit validen Dokumenten beschäftigt (außer im letzten Beispiel). Der nächste Teil zeigt, wie man mit Fehlern kontrolliert umgehen kann.

Error-Handling und Testing

Falls das JSON Dokument nicht gelesen werden kann oder die Tiefe zu hoch ist, dann gibt die json_encode()-Funktion NULL zurück. Für uns als Entwickler steht jedoch eine weitere Funktion zur Verfügung, nämlich json_last_error(). Diese enthält den Fehlercode des letzten Aufrufs und kann somit abgefangen werden. Die entsprechenden Konstanten sind hier zu finden.

  • JSON_ERROR_NONE: Kein Fehler ist aufgetreten.
  • JSON_ERROR_DEPTH: Die maximale Parsingtiefe wurde erreicht.
  • JSON_ERROR_STATE_MISMATCH: Ungültiges JSON-Dokument.
  • JSON_ERROR_CTRL_CHAR: „Control Character“-Fehler, möglicherweise falsches Encoding.
  • JSON_ERROR_SYNTAX: Syntax Error.
  • JSON_ERROR_UTF8: UTF-8 Fehler, möglicherweise falsches Encoding. (seit PHP 5.3.3).

Mit diesen Informationen ist es uns nun möglich, eine Klasse zu schreiben, welche eine aussagekräftige Exception wirft, falls ein Fehler aufgetreten ist.

 'No error has occurred',
			JSON_ERROR_DEPTH => 'The maximum stack depth has been exceeded',
			JSON_ERROR_STATE_MISMATCH => 'Invalid or malformed JSON',
			JSON_ERROR_CTRL_CHAR => 'Control character error, possibly incorrectly encoded',
			JSON_ERROR_SYNTAX => 'Syntax error',
			JSON_ERROR_UTF8 => 'Malformed UTF-8 characters, possibly incorrectly encoded'
		);

		public static function encode($value, $options = 0) {
			$result = json_encode($value, $options);

			if($result || json_last_error() == JSON_ERROR_NONE)  {
				return $result;
			}

			throw new RuntimeException(static::$_messages[json_last_error()]);
		}

		public static function decode($json, $assoc = false) {
			$result = json_decode($json, $assoc);

			if($result || json_last_error() == JSON_ERROR_NONE) {
				return $result;
			}

			throw new RuntimeException(static::$_messages[json_last_error()]);
		}

	}
	?>

Mit einer Hilfsfunktion können die Exceptions nun elegant getestet werden:

// Gibt "Correctly thrown" aus.
	assertException("Syntax error", function() {
		$string = '{"foo": {"bar": {"cool": NONUMBER}}}';
		$result = JsonHandler::decode($string);
	});

Seit PHP 5.3.3 gibt es einen JSON_ERROR_UTF8 Fehler, welcher auftritt, falls das falsche Encoding verwendet wurde. Um zu verifizieren, dass ein UTF-8 String vorliegt, kann die utf8_encode()-Funktion verwendet werden. Diese konvertiert den String in UTF-8.


Ich habe dies öfters verwendet, um die gelieferten Daten einer alten MSSQL Datenbank zu konvertieren, bevor sie an den Browser gesendet wurden.

Fazit

JSON stellt ein kompaktes und leicht lesbares Format zum Datenaustausch zwischen Endpunkten dar. Es scheint, als würde es XML als de-facto Standard im Web den Rang ablaufen. PHP liefert von Haus aus alle notwendigen Werkzeuge um mit JSON effektiv umgehen zu können und bietet (seit PHP 5.3) zahlreiche Optionen an um das Verhalten weiter zu anzupassen.

Viel Erfolg beim Datenschaufeln!

Michael Nitschinger studiert Wirtschaftsinformatik und arbeitet als Consultant in Wien. Er ist Core-Contributor des Lithium Frameworks und bloggt regelmäßig auf nitschinger.at über PHP, Scala und NoSQL. Sie erreichen ihn via Twitter unter @daschl oder per E-Mail unter michael [ätt] nitschinger.at.
Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -