303 redirect with PHP

Posted Jul. 31, 2008 in PHP

When you submit a form using a web browser the script processing the form often redirects after it has done its work to a thank you page (or similar). The response type people usually use when coding with PHP is a 302 redirect because it's the default used when issuing a Location: header. The problem with this is on a page refresh the browser is likely to submit the form again. Instead you can use a 303 redirect to prevent the form being submitted again. This post looks at what a 303 response code / redirect is and how to send one with PHP.

Typically after processing the form a script will simply display some content to show it's done (e.g. with a thank you page, or the form again in an admin system). This will always repost the data on a page refresh (although most browsers will warn you before doing so). Another alternative is to redirect to another page afterwards like this:

header("Location: http://$_SERVER[HTTP_HOST]/path/to/my/script");

This will issue the default 302 response code in PHP which means a temporary redirect. On page refresh the browser is also likely to repost the form again although this behaviour can vary between browsers and versions. Having the form be resubmitted is generally not what you want to happen - for example it may mean someone submitting an email form on your site multiple times - so you can use a 303 response instead.

A 303 response code, in the words of the W3C, is as follows:

The response to the request can be found under a different URI and SHOULD be retrieved using a GET method on that resource. This method exists primarily to allow the output of a POST-activated script to redirect the user agent to a selected resource. The new URI is not a substitute reference for the originally requested resource. The 303 response MUST NOT be cached, but the response to the second (redirected) request might be cacheable.

The different URI SHOULD be given by the Location field in the response. Unless the request method was HEAD, the entity of the response SHOULD contain a short hypertext note with a hyperlink to the new URI(s).

What this means is that the location you specify as part of your redirection should only ever be requested using the GET method and that the original page should not be requested again.

To do this in PHP you would do the following:

header("HTTP/1.1 303 See Other");
header("Location: http://$_SERVER[HTTP_HOST]/path/to/my/script");

The browser would therefore post the form to this page, then be redirected using a GET request to /path/to/my/script. If the user then refreshed the page in the browser it would again make a GET request to /path/to/my/script and not a POST to the original page.

You can also read my post on doing a 301 redirect with PHP, which is what you need to do when permanently redirecting a regular page request from one URI to another.

Related posts: