Das schließende PHP Tag am Ende einer Datei und die Sache mit der Stecknadel im Heuhaufen

Wer seit vielen Jahren mit PHP programmiert, der ist es sicherlich gewohnt, jedes geöffnete PHP-Tag auch wieder zu schließen.

So ging es mir auch, bis ich vor längerer Zeit mal zu einem Probearbeiten für einen neuen Job eingeladen war und es plötzlich hieß: “So machen wir das aber nicht mehr, das PHP-Tag wird nicht mehr geschlossen.”

Die Frage beschäftigte mich zu dem Zeitpunkt schon, warum das PHP-Tag am Dateiende nicht mehr geschlossen werden sollte. Ich habe es seit Jahren verwendet und es sind mir nie Nachteile durch die Verwendung aufgefallen. Warum nun also?

Es ist ja auch kein Fehler es zu Verwenden (maximal ein Verstoß gegen die Coding Standards), hilft aber, Fehler zu vermeiden, wenn man es weglässt.

Viele Projekte bestehen heute aus einer Vielzahl von PHP-Dateien und dank MVC über eine kontrollierte Ausgabe der Response.

Das bedeutet, dass wir in unserem Programm zu jeder Zeit die Header setzen können und diese dann erst mit dem kompletten Response gesendet werden.

Das funktioniert aber nur solange, wie noch nichts gesendet wurde und genau da liegt das Risiko des schließenden PHP-Tags.

Während ungewollte Zeichen zu Beginn der Datei relativ offensichlich sind, sind sie nach dem schließenden PHP-Tag unter Umständen quasi unsichtbar.

<?php
// irgendwelcher Code
?>

Denn sobald in irgendeiner Datei ein quasi unsichtbares Leerzeichen oder ein Zeilenumbruch dahinter folgt, werden, sofern die Ausgabe nicht gebuffert wird, auch schon die entsprechende Headerinformationen gesendet und wir würden im weiteren Verlauf unseres Programms wahrscheinlich eine Fehlermeldung zu sehen bekommen (“header already sent”).

Die entsprechende Stelle dann in mehreren hunderten oder oft sogar tausenden Dateien zu suchen wäre relativ zeitaufwendig und vor allem vermeidbar. Daher sollte auf die Verwendung verzichtet werden.

<?php
// irgendwelcher Code

Ein weiterer, noch gemeinerer, Fehler kann auftreten, wenn die Datei im Unicode gespeichert wurde. In dem Fall wird vor dem eigentlichen Dateiinhalt die Bytefolge “FE FF” (Byte Order Mark/BOM) gespeichert, die von PHP bereits auch schon als Ausgabe interpretiert wird.

Das tückische daran ist jedoch, dass man diesen Fehler nicht im normalen Editor zu sehen bekommt und ggf. mit einem Hex-Editor ran müsste.

Siehe auch:

2 Kommentare

  1. Es ist doch eh eine Schwäche von PHP Tags zu benutzen. Wenn das Mixup aus HTML, CSS, Javascript und PHP nicht möglich wäre, hätte man solche Probleme nicht.

  2. Ist wohl noch aus der Entwicklung von PHP übrig geblieben. Andere Sprachen machen es doch aber ähnlich. Und wenn man mal JSP probiert hat, dann ist die PHP Syntax doch wieder echter Luxus. ;-)

Schlagwörter: Adapter, Amazon, Animation, Annotations, Anonyme Klasse, Ant, Apache, API, Array, ArrayAccess, Attachment, AutoLoader, Bedienung, Bedingung, Benchmark, Bildbearbeitung, BOM, Bootstrap, Bot, Byte Order Mark, Callback, CamelCase, Canvas, Captcha, Cheatsheet, CLI, Closure, Cloud, CodeSniffer, Community, Comparator, Contest, Controller, Converter, CouchDB, Countable, Cronjob, CSV, CustomLibrary, Custom_Model, Data Mapper, Datei, Datenbank, Datenstruktur, Datentypen, Dating, Decorator, Dekorierer, Design Patterns, Dump, Duplikat, each, Eclipse, Entwicklung, Entwurfsmuster, Enum, Erweiterung, Eventhandling, Exception-Handling, Extension, Factory, Fehler, Flash, Foreach, Formatierung, Formular, Funktion, Futon, Header, HTML5, HTTP, IDE, If, Implementierung, InnoDB, Interceptor, Interface, isset, Iterator, Java, JavaScript, jQuery, Konfiguration, Konsole, Kontrollstruktur, kopieren, Late Static Binding, Layout, Linux, Listeners, Logging, Löschen, Magento, Magic Methods, Marketing, Methode, Model, MVC, MySQL, NetBeans, Objekt, Observable, Observer, OOP, Operator, Parameter, Partnersuche, Performance, PHP, phpMyAdmin, PHPUnit, Plugin, Proxy, Qualitätssicherung, Query, Reflection, Request, Response, Rest-API, Rockstar, Routing, S3, Samba, Scheifen, Schleife, Schutz, Secure Shell, Selbstreferenz, Shop, Sicherheit, Sicherung, Singleton Pattern, SOAP, Sortierung, Sourcecode, Spam, Speicherproblem, Spickzettel, SPL, SSH, Statement, Stellvertreter, Strategy Pattern, Stream, String, Sun VirtualBox, Support, Switch, Symfony, Symfony2, Symfony Live, Tag, Template, Template Method, Ternär Operator, Testing, Thumbnail, Tool, Tour, Twig, Type-Cast, Umwandlung, Underscore, unset, Vererbung, Verzweigung, Video, Videospiel, Virtualisierung, Visitor Pattern, Vorschaubild, walk, Webserver, Webservice, Weiterleitung, Wrapper, Youtube, Zeitsteuerung, Zend Framework, Zend_Cloud, Zend_CodeGenerator, Zend_Http_Client, Zend_Service, Zugriffsmethode