Wann htmlentities() anwenden?

Jörg Kruse

Als ich anfing, PHP zu lernen, stellte sich mir schon früh die Frage, wann genau man die Funktion htmlentities() anwenden sollte, mit der Sonderzeichen für die Ausgabe in HTML codiert werden. Wichtig ist dies nicht nur, damit Browser bei Nichtangabe des Zeichensatzes die betreffenden Zeichen trotzdem richtig anzeigen, sondern auch, damit die HTML-Steuerzeiche <, >, & und " maskiert werden und Cross-Site-Scripting, d.h. die Ausgabe von an anderer Stelle eingegebener bösartiger Scripte, auf diese Weise verhindert wird.

Als Autodidakt stieß ich bei meiner ersten Suche nach einer Antwort im Netz vorwiegend auf die Meinung, dass htmlentities() gleich nach Eingabe in Formularen anzuwenden ist. Der Text landet dann bereits html-codiert in der Datenbank und braucht zur Ausgabe nicht mehr codiert werden. Da in vielen Fällen die betreffenden Daten nur einmal eingegeben, aber oft ausgegeben werden, sei dies die ökonomischere Variante, da die Funktion nur einmal ausgeführt werden braucht, nämlich direkt nach der Eingabe. Mir leuchtete dies ein, so dass auch ich mich entschloss, vor der Datenbankeingabe die Daten entsprechend zu behandeln.

Mehrmals gab es später allerdings das Problem, dass ich Daten in das Format zurückverwandeln musste, welches sie vor der Eingabe in die Datenbank aufwiesen, da das HTML-Format oder andere Formatierungen für die Ausgabe ungeeignet waren.

  • Für das Versenden des Textes in einer gewöhnlichen Text-Email (z.B. einer Benachrichtigungmail nach einer Eingabe) ist HTML-Code ungeeignet, so dass dieser mit html_entity_decode() behandelt werden muss.
  • Für die Ausgabe in ein Textfeld (textarea), z.B. zum Editieren des Textes, ist der HTML-Zeilenumbruch <br /> ungeeiget, eine Funkion die das nl2br() rückgängig macht, stellt PHP nicht zur Verfügung, wohl auch weil je nach Betriebssystem bei der ersten Eingabe eine andere Codierung für den Zeilenumbruch vorgelege haben kann (Windows: \r\n, Unix: \n, Mac: \r). Hier gelangt man sehr schnell zum Schluss, dass der Zeilenumbruch am besten erst bei der Ausgabe umgewandelt wird, da man erst dann weiß, welches Format man überhaupt benötigt.
  • In RSS-Files (1.0) sind htmlentities fehl am Platz, der Parser wirft bei einem &ouml; für ö einen Fehler aus, so dass die Datei gar nicht ausgegeben werden kann. Das Argument, dass man bei vielen Ausgaben die HTML-Codierung erspart, wenn diese gleich zu Anfang vorgenommen wird, relativiert sich hier endgültig: auf RSS-Files wird naturgemäß sehr oft zugegriffen, und jedesmal muss eine vorherige HTML-Codierung wieder rückgängig gemacht werden.
  • Manchmal übergibt man Daten, wie z.B. den Titel eines Beitrages, als GET-Parameter in die URL, genauer gesagt in den QUERY_STRING - Sonderzeichen wie die Umlaute können dabei mit einer selbst erstellten Funktion sowohl URI-kompatibel als auch suchmaschinenoptimiert umgewandelt werden (z.B. ö in oe); dies setzt allerdings voraus, dass die Zeichen zuvor nicht htmlcodiert wurden. htmlentities() verstümmelt zudem Umlautdomains in Links, wie z.B. href="jörg-kruse.de" zu href="j&ouml;rg-kruse.de", so dass diese nicht mehr aufgerufen werden können..

Trägt mal einmal die Ausnahmefälle von der Regel HTML zusammen, so erkennt man, dass eine Anwendung von hmlentities vor der Eingabe (INSERT) in die Datenbank viele Probleme schafft. Ich hatte deswegen nach reiflicher Überlegung, die Scripte für mein neues Forum nochmal komplett überarbeitet - denn später ließe sich dies nur noch sehr schwer wieder korrigieren. Die Daten sind jetzt in einem neutralen Format gespeichert (d.h. lediglich behandelt durch addslashes(), um SQL Injections zu verhindern). Erst nach dem Auslesen (SELECT) aus der Datenbank werden die Daten für die jeweilige Ausgabe behandelt, das ist für mich inzwischen die sauberste Lösung.

Fragen zu diesem Themenbereich können in meinem PHP-SQL-Forum gestellt werden