I had been using the Slim PHP Microframework with great success building an AngularJS single page web application with a REST backend. Everything was fast, only minimal amounts of data was exchanged between client and server — and then I ran into trouble. Most of my REST responses would set a HTTP content type of application/json. While this worked fine on IIS on Windows, on Apache/Linux the content type would always revert to text/html.

Now typically when your HTTP headers don’t get set by the Slim PHP microframework, the problem is in your PHP scripts. It’s likely that there’s some whitespace, or other content, before the opening <?php tag somewhere, or after the closing ?> tag, and any content output before the headers are set discards the headers. This is one of the reasons why PHP developers (except those actually mixing PHP and HTML) no longer use the closing ?> tag in their PHP scripts: one less spot where there may be undesired output. So I scoured my codebase for opening PHP tags to see if there was any whitespace before them anywhere. There wasn’t. Perhaps in the many scripts I had included under /vendor using composer? Also no.

So, testing further, I made a Slim GET route with content-type application/json that returned no content at all. Zero bytes. Zero bytes indeed on IIS, but 3 bytes on Apache (and 23 bytes total transferred – but that’s likely due to gzip compression actually increasing this byte count). Where are there 3 bytes? The response body contains zero bytes, so somehow this content is invisible in the response body…

I turned to file encodings. I noticed that while most of my files were UTF8 with LF line endings, a few had CRLF. For one or two files, I converted CRLF to LF and re-uploaded to the Linux server. No change! Still, I felt convinced the problem had to be a BOM marker in some PHP files that would explain the extra bytes on Apache. But if the problem didn’t occur on Windows, then where did these markers and encoding differences come from?

Then I vaguely remembered that there was one file I had once created through FileZilla, directly on the server, by using FileZilla’s “create file” command. I decided to recreate the file on Windows, deleting it from the server and re-uploading it. And presto: the problem went away!

TL;DR: I created a file on the webserver through FileZilla FTP, and it turned out to have some kind of invisible BOM marker that sent extra bytes to Apache, thus discarding any HTTP headers my code set.