Wednesday, June 13, 2007

I haven't posted much, but at php|tek 2007, Chris Shiflett actually said he liked my rant, and that I should post more.

Well, hey, if Chris Shiflett says I oughta do something, I listen.

So, today's rant is about PHP header Location hacks.

First, let's be sure everybody understands what it is:

header("Location: http://example.com");

will re-direct the browser to the URL example.com

Specifically, the PHP tells Apache to issue to the browser a 301 Redirect header to that URL, and then the browser gets that 301 Rediret header and automatically tries to visit that URL.

EDITAs pointed out on PHP-General, PHP actually sends a 302 Temporarily Moved rather than a 301 Permanently moved. The rest of the rant still applies, as I simply mis-typed 301 for 302 anyway./EDIT

Now this seems really cool at first, perhaps because it is really cool, when used for an appropriate problem.

Unfortunately, many PHP scripters are using this as an Idiom or as a Programming Construct with things like:

if (!logged_in()){ header("Location: login.php");}

Now, this does "work" but there are several problems with it.

First and foremost, the HTTP Specs require a complete URI for the location. And while this fragment of a URI might "work" on most browsers, it will, sooner or later, totally mess you up when the browser mis-interprets this.

Specifically, some versions of IE will do the redirect, but won't POST the original data as a redirect should, with this URI fragment. Use the full URL, and IE actually does the right thing, and redirects with all the POST data intact.

You shouldn't use an incomplete URI just because "it works" any more than you should use non-compliant HTML just because it works.