Pssst, ich verkaufe auch Templates!

Simon Stamm

Problematik

Wer kennt das Problem nicht? Man benutzt Umlaute in HTML/PHP-Dateien, verzichtet auf die HTML-Schreibweise (z.B. ä) und schon werden im Browser anstatt der Umlaute nur noch Fragezeichen angezeigt.

Um Probleme mit den Umlauten bei Ausgaben zu vermeiden, sollten alle Dateien in UTF-8 statt ANSI gespeichert werden. Dadurch werden die Umlaute zwar korrekt angezeigt, doch bringt das meist einige Probleme mit sich:

  • Die Zeichen ï»¿ erscheinen am Anfang.
  • Es wird eine leere/weiße Seite angezeigt.
  • Im Internet Explorer und ggf. anderen Browsern stimmt die Ausrichtung nicht mehr.
  • Einige JavaScript-Funktionen (besonders jQuery/Mootols-Effekte) funktionieren nicht.
  • Der BOM wird in einem HTML-Validator als Warnung angezeigt.

Wird in PHP z.B. mit der Funktion header() oder session_start() gearbeitet, kann es zu folgendem Fehler kommen:

Warning: session_start() [function.session-start]: Cannot send session cache limiter – headers already sent (output started at /var/www/example.php:1) in /var/www/example.php on line 1

Ursache

Der Grund für die Probleme ist, dass beim Speichern als UTF-8 am Anfang der Datei ein „Byte Order Mark“ (kurz: BOM) geschrieben wird. Der BOM für UTF-8 lautet U+FEFF und ist drei Bytes groß – 0xEF, 0xBB und 0xBF. Die drei Bytes werden nach Windows-1252 als „“ dargestellt. Für UTF-16 und UTF-32 wird das BOM für die Byte-Reihenfolge verwendet, welches bei UTF-8 nicht wirklich notwendig ist.

Leider interpretieren Browser bzw. PHP den BOM nicht richtig. Insbesondere PHP denkt, dass bereits eine Ausgabe stattgefunden hat, sodass es zu spät ist, den Header zu verändern. Der Fehler tritt bei ANSI nicht auf, weil dieser keinen BOM besitzt.

Lösung

Die Lösung ist einfach: Die Datei muss mit der Kodierung „UTF-8 ohne BOM“ gespeichert werden.

Windows

Dies kann z.B. mit Notepad++ erledigt werden, indem man die Datei mit dem Editor öffnet und dann die Kodierung mittels Kodierung -> UTF8 ohne BOM erneut abspeichert.

UTF-8 ohne BOM in Notepad++

Linux

Eine elegante Lösung, um in einem Ordner alle PHP-Dateien (inkl. Unterordner) nach dem BOM zu durchsuchen und anschließend zu löschen, kann mittels der Bash erreicht werden.

find . -type f -iname "*.php" -exec sed '1s/^\xEF\xBB\xBF//' -i.bak {} \; -exec rm {}.bak \;

Möchte man nur die Dateien mit dem BOM aufspüren, kann dieser Einzeiler verwendet werden.

grep -rl $'\xEF\xBB\xBF' .

Natürlich geht das auch mit VIM.

# vim utf8_with_bom.php
:set nobomb
:wq

PHP

Das BOM kann auch mit PHP5 entfernt werden. Dadurch müssen die drei Bytes erkannt und gelöscht werden.

$str = file_get_contents('utf8_with_bom.php');
$bom = pack("CCC", 0xef, 0xbb, 0xbf);
if (0 == strncmp($str, $bom, 3)) {
	echo "BOM detected - file is UTF-8\n";
	$str = substr($str, 3);
}

PHP 6 wird Unicode Support erhalten, wodurch man sich nicht mehr mit diesem Problem rumärgern muss. Es wird korrekt mit PHP-Dateien, die das BOM beinhalten, umgehen können.

  • Daniel_aus_TUT

    Geschrieben: 30. November 2015


    Hi Simon,
    Danke für den Beitrag!!!!
    Ich hatte genau dieses Problem und bin fast verzweifelt: PHP hat dadurch die Session ID nicht angelegt.
    Jetzt funktioniert alles perfekt! :-)

    Gruss Daniel Antworten


    • Simon Stamm

      Geschrieben: 30. November 2015


      Schön, dass ich dir mit dem Beitrag helfen konnte, Daniel! :) Antworten


  • Peter

    Geschrieben: 7. März 2017


    Hi Simon,

    für Deinen Beitrag danke ich Dir herzlich!
    Seit mein Provider auf PHP 5.6 umgestellt hatte, fingen die Probleme auch auf meinen Webseiten an.
    Die Umstellung auf UTF-8 half schon - doch erst Dein Hinweis auf den BOM brachte die Erleuchtung!
    Danke nochmals!
    Herzliche Grüße
    Peter Antworten


    • Simon Stamm

      Geschrieben: 16. März 2017


      Hey Peter,



      mich freut sehr, dass ich dir mit dem Beitrag helfen konnte!



      Liebe Grüße

      Simon Antworten


  • Bernd

    Geschrieben: 17. April 2019


    Vielen Dank für diesen Artikel. Ihr habt mir bei meinem kleinen aber fatalen Problem sehr geholfen :-) .
    Jeden Tag eine gute Tat.... Dieses habt ihr an mir gerade erfüllt.

    Super lieben Dank Antworten


  • Fritz

    Geschrieben: 27. März 2020


    Herzlichen Dank für die ausführliche Erklärung und auch gleich den adäquaten Lösungsvorschlägen, hat mir ein wenig Tipparbeit abgenommen.

    Grüße und Gsund bleiben !

    Fritz Antworten


  • Peter, PHP-Freelancer

    Geschrieben: 16. Februar 2022


    Hi Simon, Danke für den wertvollen Beitrag! Als PHP-Freelancer ist man immer wieder froh, wenn man Problemchen nicht selber lösen muss, sondern auf solch wertvolle Ressourcen zurückgreifen kann. Antworten


  • Obi

    Geschrieben: 27. April 2022


    Hi Simon, ich hatte den Effekt zwar mit dem Nodepad++ Plugin HEX-Editor zwar erkannt, aber die Lösung in deinem Beitrag erklärt gefunden. Vielen Dank Obi Antworten


  • Carport

    Geschrieben: 14. Februar 2023


    Danke für die tolle Arbeit die hier geleistet wurde, hier bekommt man sehr gute Informationen, die sehr nützlich sein können.

    Lieben Gruß Mia Antworten



  • Du kannst diese HTML Tags und Attribute benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>