Beware of new lines in your PHP include files

Bewareofmonkeys
Photo by Ben Romberg

The single best thing about PHP is how easy it is to embed HTML within your source files. This makes writing user-interface oriented code incredibly easy, since you can prototype both the presentation and the logic of your pages in the same file.

As always though, there’s a price, as I discovered after some serious head-scratching yesterday. All the executable code in a PHP file is enclosed in special <?php?> blocks. A typical project will have a bunch of included PHP files, with the each file internally enclosed in one of these tags. Anything in those files that’s outside the tag is printed verbatim to the standard output, usually the user’s web browser. That means if you have a new line after the closing tag in an include, that will be printed to the output.

Normally that’s not a problem, floating carriage returns are generally treated as whitespace and ignored in HTML, so it doesn’t make a difference. What if you’re actually trying to pass binary data to the user though? In my case, I’m fetching a mail attachment from a database, setting up the appropriate MIME content type and then printing it to standard output to be downloaded. That nearly invisible new line at the end of one of the include files gets output first, which royally confuses most binary formats, making them unrecognizably corrupted.

Once I figured out what was going on, I did a sweep through my includes and removed any trailing new lines, but I could also have called ob_clean() to wipe the output buffer before I wrote out the file data. There’s a good treatment of the whole topic of file downloads in PHP here, but it feels like the deeper lesson is about using the right tool for the job. PHP is extremely fast to prototype web apps in because it is totally focused on the task of producing HTML pages, but once you’re dealing with arbitrary data, Perl or Python sure start to look pretty.

One response

  1. Pingback: Set Http Headers & PHP tags | Tech Bang Bang

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: