All in the <head> – Ponderings and code by Drew McLellan –

And Breathe Out

PHP has been giving me the run-around. Just when you think you’ve got it all sussed out it springs another surprise. It likes to play with me that way – show me who’s boss.

This afternoon Nathan and I launched a site we have been working on for months. More accurately, we launched a site based on the content management system we’ve been working on for months. She flies! Hurrah and all that. Up until the site going live today I’d been validating pages using one or other of two methods. The first thing I tried was installing the W3C validator on my dev server. That almost worked, but no matter what input I gave it seemed to be resolving paths to the wrong site. I don’t think it liked by VirtualHosts set up. Being too pressed for time to really fiddle with it, I resorted to saving the output of a view source to disc and uploading the file to the W3C service. This worked fine.

On enlivening the site this afternoon, I took the opportunity to run the validator across the site for real. You can guess what happened. Errors galore – and all down to PHP’s automatic handling of sessions. For those not familiar with its behaviour, PHP uses cookies to store a session id on the client in the usual way. However, when cookies aren’t enabled PHP steps in and saves your bacon by automatically rewriting all the links on a page to append the session id to the query string. I’ve written similar functionality myself for ASP systems and it’s no small task, so having this feature built in is a real bonus. It’s just a shame it doesn’t encode its ampersands when it does it.

If you’ve not got access to the php.ini, whack this in your page:

ini_set("arg_separator.output", "&amp;");

So we’re all cool now, right? Wrong – to maintain the session through HTTP POSTs, PHP also jimmies a hidden input into any forms, right after the opening form tag. This is just fine and dandy, but for the fact that XHTML 1.0 Strict requires that all input elements (including those which are not visually represented) are contained inside a block-level element.

PHP handles this by … invalidating your page. Thanks guys. I see this bug was opening in September 2001. I got the work-around from the notes on that bug, but it’s not pretty. The first thing to do, again if you don’t have access to the php.ini, is to place this on your page:

ini_set("url_rewriter.tags", "a=href,area=href,frame=src,input=src");

That’s basically just reconfiguring the URL rewriter to not attempt to fix up forms – no hidden field will be written. That means, however, that you’ve got to write the field yourself.

@