Fabricated Technobabble

View Original

Headers already sent?!

In my experience, the most annoying and hard to track down bugs are the simplest things. Sometimes you misspell a word. Sometimes you accidentally check for a boolean true when you should be checking for false. The worst are misplaced spaces, tabs, carriage returns and other whitespace that makes an bug hard to track down. ...

What I was trying to do was simple. I just needed to add a class file into my PHP code for an application I am working on. After I added the class file like so:

require_once( "../../../fileDirectory/my_necessary_class.php" );

I started to get errors.

Because this was a Flex application using AMFPHP, my first error popped up in the service browser.

TypeError: Error #1009: Cannot access a property or method of a null object reference.	at RawAmfService/internal::readData()
	at flash.events::EventDispatcher/flash.events:EventDispatcher::dispatchEventFunction()
	at flash.events::EventDispatcher/dispatchEvent()
	at flash.net::URLLoader/flash.net:URLLoader::onComplete()
	at [io]

Ack! Near useless errors, at least it looked like the AMF reading abilities of the flash player were being confounded by whatever they were getting sent. From what eventually came up in the Service Browser's results window I had a bit more information to work with:

(Object)#0
  message = "faultCode:INVALID_AMF_MESSAGE faultString:'Invalid AMF message' faultDetail:'

Warning: Cannot modify header information - headers already sent by (output started at /a/long/path/to/a/site/root/fileDirectory/my_necessary_class.php:464) in /a/long/path/to/a/site/root/amfphp/core/shared/exception/php4Exception.php on line 38
'"
  name = "Error"
  rootCause = (null)

Eureka! proper AMF file headers were not able to be sent because, headers were already sent before the call to send AMF headers.

My deductive process to find the error went like this:
1. Perhaps the file isn't where I think it is. I change the require_once code a little and get an error that tells me that I had it right before.
2. Look for any obvious errors in the class - it works in other programs so I wasn't counting on this to work out for me. It didn't.
3. So that I could edit the class without breaking other applications I made a copy in the same directory and to see if somehow tha was affecting the headers. Still a no go.
4. Finally I decided to comment the entire file out and try it. Success! Slowly I uncommented function by function. In the end I uncommented every function and it still worked.

Not being one to fix a bug without understanding it I did a comparison of the original file and my new version. The only difference was my new version did not have an extra line after the closing ?>. When I saw that I remembered something I read about the PHP include functions( include, include_once, require and require_once ).

When a file is included, parsing drops out of PHP mode and into HTML mode at the beginning of the target file, and resumes again at the end. For this reason, any code inside the target file which should be executed as PHP code must be enclosed within valid PHP start and end tags.

What was happening was that the last line of that file was being sent as HTML, so PHP sent regular HTML headers when the file was included and before the AMF headers were sent. So if you are trying to output non-HTML and your run into a problem where the wrong headers are being sent, check to see if you have some extra whitespace outside of your <?php ?> tags.

----
Daryl "Deacon" Ducharme is currently Director of Application Development for the Interactive Agency Provis Media Group, LLC which helps organizations enhance identity, connect with customers and increase productivity.