[ Team LiB ] Previous Section Next Section

Redirecting the User

Our simple script still has one major drawback. The form is rewritten whether or not the user guesses correctly. The fact that the HTML is hard-coded makes it difficult to avoid writing the entire page. We can, however, redirect the user to a congratulations page, thereby sidestepping the issue altogether.

When a server script communicates with a client, it must first send some headers that provide information about the document to follow. PHP usually handles this task for you automatically, but you can choose to send your own header lines with PHP's header() function.

To call the header() function, you must be sure that no output has been sent to the browser. The first time that content is sent to the browser, PHP sends out headers and it is too late for you to send your own. Any output from your document, even a line break or a space outside of your script tags, causes headers to be sent. If you intend to use the header() function in a script, you must make certain that nothing precedes the PHP code that contains the function call. You should also check any libraries that you might be using.

Listing 10.9 shows a request (lines 1 and 2) followed by typical response headers sent to the browser by PHP.

Listing 10.9 A Request Prompts Response Headers from a PHP Script
 1: HEAD /phpbook/source/listing10.8.php HTTP/1.0
 2: Host:matt.corrosive.co.uk
 4: HTTP/1.1 200 OK
 5: Date: Wed, 03 Sep 2003 13:52:09 GMT
 6: Server: Apache/2.0.47 (Unix) PHP/5.0.0b1
 7: X-Powered-By: PHP/5.0.0b1
 8: Connection: close
 9: Content-Type: text/html; charset=ISO-8859-1

You Can Browse the Web with Telnet


You can see headers sent in response to a request by using a Telnet client. Connect to a Web host at port 80 and then type

HEAD /path/to/file.html HTTP/1.0

followed by two returns. The headers should appear on your client.

By sending a "Location" header instead of PHP's default, you can cause the browser to be redirected to a new page:

header( "Location: http://www.corrosive.co.uk" );

Assuming that we have created a suitably upbeat page called congrats.html, we can amend our number-guessing script to redirect the user if she guesses correctly, as shown in Listing 10.10.

Listing 10.10 Using header() to Send Raw Headers
 1: <?php
 2: $num_to_guess = 42;
 3: $message = "";
 4: if ( ! isset( $_POST['guess'] ) ) {
 5:    $message = "Welcome to the guessing machine!";
 6: } else if ( $_POST['guess'] > $num_to_guess ) {
 7:    $message = $_POST['guess']." is too big! Try a smaller number";
 8: } else if ( $_POST['guess'] < $num_to_guess ) {
 9:    $message = $_POST['guess']." is too small! Try a larger number";
10: } else { // must be equivalent
11:     header("Location:congrats.html");
12:     exit;
13: }
14: $guess = (int) $_POST['guess'];
15: $num_tries = (int) $_POST['num_tries'];
16: $num_tries++;
17: ?>
19:     "-//W3C//DTD XHTML 1.0 Strict//EN"
20:     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
21: <html>
22: <head>
23: <title>Listing 10.10 A PHP Number Guessing Script</title>
24: </head>
25: <body>
26: <div>
27: <h1>
28: <?php print $message ?>
29: </h1>
30: Guess number: <?php print $num_tries?><br/>
32: <form method="post" action="<?php print $_SERVER['PHP_SELF']?>">
33: <p>
34: <input type="hidden" name="num_tries" value="<?php print $num_tries?>" />
35: Type your guess here: <input type="text" name="guess"
36:                         value="<?php print $guess?>"/>
37: </p>
38: </form>
39: </div>
40: </body>
41: </html>

The else clause of our if statement on line 10 now causes the browser to request congrats.html. We ensure that all output from the current page is aborted with the exit statement on line 12, which immediately ends execution and output, whether HTML or PHP.

Remember that sending content to the browser causes HTTP headers to be sent. If you then call the header() function, you cause an error. You code defensively by checking that headers have not been sent before calling header():

if ( ! headers_sent() ) {
    header( "Location: http://www.example.com" );

If headers have been sent, the headers_sent() function returns true. headers_sent() also optionally accepts two empty variables, into which it places the filename and line number, defining the point at which headers were sent. This function can be very useful for debugging:

if ( headers_sent( $file, $num ) ) {
    print "headers were sent in file: $file on line: $line";

    [ Team LiB ] Previous Section Next Section