Wenn HTML-Sonderzeichen mit htmlspecialchars() kodiert wurden, liegen sie als sogenannte HTML-Entities vor. Zeichen wie <, >, &, " und ' werden dabei in ihre sicheren Entity-Darstellungen umgewandelt. Mit htmlspecialchars_decode() lässt sich dieser Vorgang umkehren: Die Funktion wandelt die Entities wieder in die ursprünglichen Sonderzeichen zurück. In diesem Tutorial erfährst du, wie die Funktion funktioniert, welche Parameter sie bietet und worauf du bei der Sicherheit achten musst.

Zuerst wird geklärt, welche Entities die Funktion überhaupt zurückwandelt und wo die Grenze zu html_entity_decode() liegt.
Was macht htmlspecialchars_decode()?
Die Funktion htmlspecialchars_decode() ist das Gegenstück zu htmlspecialchars(). Sie wandelt die fünf speziellen HTML-Entities zurück in ihre ursprünglichen Zeichen:
& wird zu & < wird zu < > wird zu > " wird zu " ' wird zu ' (nur mit ENT_QUOTES)
Alle anderen HTML-Entities wie ö oder bleiben dabei unverändert. Genau das unterscheidet die Funktion von html_entity_decode(), die sämtliche Entities zurückwandelt.
Syntax und Parameter
Die Funktion erwartet einen String und optional einen flags-Parameter sowie einen Zeichensatz:
htmlspecialchars_decode(string $string, int $flags = ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401): string
Der erste Parameter ist der zu dekodierende String. Der zweite Parameter steuert, welche Anführungszeichen zurückgewandelt werden und welcher Dokument-Typ gilt.
Der flags-Parameter
Der flags-Parameter akzeptiert mehrere Konstanten, die sich mit dem Bitwise-OR-Operator (|) kombinieren lassen:
Anführungszeichen-Flags:
ENT_COMPAT: Wandelt nur doppelte Anführungszeichen (") zurück ENT_QUOTES: Wandelt sowohl doppelte (") als auch einfache (') Anführungszeichen zurück ENT_NOQUOTES: Wandelt keine Anführungszeichen zurück
Dokument-Typ-Flags:
ENT_HTML401: Behandelt den String als HTML 4.01 ENT_HTML5: Behandelt den String als HTML5 ENT_XML1: Behandelt den String als XML 1 ENT_XHTML: Behandelt den String als XHTML
Das Flag ENT_SUBSTITUTE ersetzt ungültige Code-Sequenzen durch ein Unicode-Ersetzungszeichen, anstatt einen leeren String zurückzugeben.
Beispiele
Die folgenden Beispiele zeigen die Funktion in der Praxis.
Grundlegende Verwendung
<?php
$kodiert = '<p>Hallo & Willkommen</p>';
$dekodiert = htmlspecialchars_decode($kodiert);
echo $dekodiert;
/* <p>Hallo & Willkommen</p> */
Die Entities <, > und & werden in die entsprechenden Sonderzeichen zurückgewandelt. Das Ergebnis ist ein gültiger HTML-String mit echten Tags.
Anführungszeichen dekodieren
<?php
$text = 'Er sagte "Hallo" und 'Tschuess'';
echo htmlspecialchars_decode($text);
/* Er sagte "Hallo" und 'Tschuess' */
echo htmlspecialchars_decode($text, ENT_QUOTES);
/* Er sagte "Hallo" und 'Tschuess' */
Ohne das Flag ENT_QUOTES werden einfache Anführungszeichen (') nicht dekodiert. Erst mit ENT_QUOTES wandelt die Funktion beide Typen von Anführungszeichen zurück.
Unterschied zu html_entity_decode
Während htmlspecialchars_decode() nur die fünf speziellen Entities zurückwandelt, dekodiert html_entity_decode() sämtliche HTML-Entities. Dazu zählen benannte Entities wie ö, ü, sowie numerische Entities wie © oder €. Für die Dekodierung von mit htmlspecialchars() kodierten Strings ist htmlspecialchars_decode() die passende Wahl. Wurde der String hingegen mit htmlentities() kodiert, sollte html_entity_decode() verwendet werden.
htmlspecialchars vs. htmlspecialchars_decode
Die beiden Funktionen bilden ein Paar: htmlspecialchars() kodiert Sonderzeichen in sichere Entities, htmlspecialchars_decode() macht diese Umwandlung rückgängig. Der folgende Code zeigt den vollständigen Kreislauf:
<?php
$original = '<script>alert("XSS")</script>';
$sicher = htmlspecialchars($original, ENT_QUOTES, 'UTF-8');
echo $sicher;
/* <script>alert("XSS")</script> */
$zurueck = htmlspecialchars_decode($sicher, ENT_QUOTES);
echo $zurueck;
/* <script>alert("XSS")</script> */
Das folgende Diagramm veranschaulicht diesen Zusammenhang:
flowchart LR
A[Zeichen] -->|htmlspecialchars| B[Entities]
B -->|htmlspecialchars_decode| A
B -->|sichere Ausgabe| C[Browser]
Wichtig ist, dass beim Dekodieren die gleichen Flags verwendet werden wie beim Kodieren. Wurde htmlspecialchars() mit ENT_QUOTES aufgerufen, sollte auch htmlspecialchars_decode() mit ENT_QUOTES arbeiten, damit alle Entities korrekt zurückgewandelt werden.
Sicherheitsaspekte
Die Verwendung von htmlspecialchars_decode() auf Benutzereingaben kann gefährlich sein. Wenn du zuvor kodierte Sonderzeichen wieder dekodierst, bevor sie im HTML ausgegeben werden, öffnest du die Tür für Cross-Site Scripting (XSS). Ein Angreifer könnte schadhaften JavaScript-Code einschleusen, der nach der Dekodierung vom Browser ausgeführt wird. Dekodiere Strings daher nur dann, wenn du sicher bist, dass sie aus einer vertrauenswürdigen Quelle stammen. Im Zweifel sollten Benutzereingaben immer kodiert bleiben, bis sie bewusst als HTML interpretiert werden sollen.
Fazit
htmlspecialchars_decode() ist das exakte Gegenstück zu htmlspecialchars() und wandelt die fünf speziellen HTML-Entities zurück in ihre ursprünglichen Zeichen. Mit dem flags-Parameter lässt sich steuern, ob auch Anführungszeichen dekodiert werden. Für die vollständige Dekodierung aller HTML-Entities ist html_entity_decode() die richtige Wahl. Bei der Arbeit mit Benutzereingaben ist Vorsicht geboten: Dekodierte Strings sollten nur dann im HTML ausgegeben werden, wenn die Quelle vertrauenswürdig ist.