Using Output Buffering


An interesting feature added in version 4 of PHP is output control. Output control (or output buffering) allows you to write and execute your scripts as normal but send data to the Web browser only at select points. The main benefit of this system is that you can call the header(), setcookie(), and session_start() functions at nearly any spot in your script without concern for the headers already sent error messages.

To begin output buffering, use the ob_start() function. Once you call it, every echo(), print(), and similar function will send data to a memory buffer rather than the Web browser. Conversely, HTTP calls (like header() and setcookie()) will not be buffered and will operate as usual.

At the conclusion of the script, call the ob_end_flush() function to send the accumulated buffer to the Web browser. Or, use the ob_end_clean() function to delete the buffered data without sending it. Both functions have the secondary effect of turning off output buffering.

From a programmer's perspective, output buffering allows you to structure a script in a more linear form, without concern for HTTP headers. To demonstrate how you might use output buffering, I'll create a straightforward version of a login.php script, similar to those written in Chapter 9, "Cookies and Sessions."

To use output buffering

1.

Create a new PHP document in your text editor (Script 11.4).

 <?php # Script 11.4 - login.php 

Script 11.4. The login.php script can be written in a more logical structure without regard to HTTP headers, thanks to the use of output buffering.


2.

Begin output buffering and close the PHP section.

 ob_start(); ?> 

The key to using output buffering is to call the ob_start() function as early as possible in a script. It should be the very first line (not counting the opening PHP tag).

3.

Add the HTML header.

 <!DOCTYPE html PUBLIC "-//W3C//DTD  XHTML 1.0 Transitional//EN "http://www.w3.org/TR/xhtml1/DTD/  xhtml1-transitional.dtd> <html xmlns="http://www.w3.org/1999/  xhtml xml:lang="en" lang="en"> <head>   <meta http-equiv="content-type"    content="text/html; charset=    iso-8859-1 />   <title>Login</title> </head> <body> 

Since this code comes after output buffering has started, the HTML will be stored in memory, rather than sent to the Web browser.

If you are using a template system in your page, you could include the header file here instead.

4.

Check if the form has been submitted and include the database connection script.

 if (isset($_POST['submitted'])) {   require_once ('../mysql_connect.    php); 

In this script I assume that a mysql_connect.php script exists that establishes the database connection. That page should also define the escape_data() function. See the example in Chapter 9 if you don't have such a script sitting around already.

5.

Validate the email address and password.

 if (!empty($_POST['email'])) {   $e = escape_data($_POST['email']); } else {   echo '<p><font color="red">    You forgot to enter your email    address!</font></p>';   $e = FALSE; } if (!empty($_POST['password'])) {   $p = escape_data($_POST    ['password]); } else {   echo '<p><font color="red">    You forgot to enter your password!    </font></p>';   $p = FALSE; } 

Instead of using an $errors array to handle errors (as I have in previous incarnations), I can now directly print the messages. Each string will be added to the current buffer, rather than sent to the Web browser.

6.

Query the database.

 if ($e && $p) {   $query = "SELECT user_id,    first_name FROM users WHERE    email='$e AND password=    SHA('$p)";   $result = @mysql_query ($query);   $row = mysql_fetch_array    ($result, MYSQL_NUM); 

Hopefully this part of the code is second nature to you by now. A query is run retrieving the user's ID and first name from the database, using the submitted email address and password in the WHERE conditional.

7.

If a match was made, store the data in the session, delete the buffer, and redirect the user.

 if ($row) {   session_start();   $_SESSION['user_id'] = $row[0];   $_SESSION['first_name'] = $row[1];   ob_end_clean();   $url = 'http://' . $_SERVER    ['HTTP_HOST] . dirname($_SERVER    ['PHP_SELF]);   if ((substr($url, -1) == '/') OR    (substr($url, -1) == '\\') ) {   $url = substr ($url, 0, -1);   }   $url .= '/loggedin.php';   header("Location: $url");   exit(); 

If the submitted email address and password match those in the database, then $row will have a value and I can register the first name and user_id values to the session. Thanks to output buffering, I can call the session_start() function here, even though there are HTML and echo statements in the preceding code.

Since I won't be using the buffered text if the user is redirected, I call the ob_end_clean() function before header(), which will delete the existing buffer and stop output buffering.

Finally, the user is redirected to a loggedin.php page. The code for determining the absolute URL for redirection was explained in detail in Chapter 8.

8.

Complete the ($row) conditional.

 } else {   echo '<p><font color="red">    The email address and password    entered do not match those on    file.</font></p>';   echo '<p><font color="red">' .    mysql_error() . '<br />    <br />Query: ' . $query .    '</font></p>'; } 

The $row variable could not have a value either because of a SQL/MySQL error or because an improper email address/password combination was entered. The first message here covers the second case and is what a public user should see. The second message is for your own debugging purposes and should not be part of a live application.

9.

Complete the ($e && $p) conditional, close the database connection, close the submit conditional, and close the PHP block.

  } else {   echo '<p><font color="red">    Please try again.</font>    </p>';   }   mysql_close(); } ?> 

10.

Make the HTML form.

 <h2>Login</h2> <form action="login.php"  method="post>   <p>Email Address: <input type=    "text name="email" size="20"    maxlength="40 value="<?php    if (isset($_POST['email]))    echo $_POST['email]; ?>" />    </p>   <p>Password: <input type=    "password name="password"    size="20 maxlength="20" /></p>   <p><input type="submit" name=    "submit value="Login" /></p>   <input type="hidden" name=    "submitted value="TRUE" /> </form> 

11.

Complete the HTML page and flush the buffer.

 </body> </html> <?php ob_end_flush(); ?> 

The second to the last line in the script will send all of the accumulated data to the Web browser and turn off output buffering.

12.

Save the file as login.php, upload to your Web server, and test in your Web browser (Figure 11.14).

Figure 11.14. If any error messages occur, they are immediately printed and the form is displayed again.


For the entire process to work, a loggedin.php script is required, which I'll quickly write out.

To create loggedin.php

1.

Create a new PHP document in your text editor, beginning with the ob_start() function (Script 11.5).

 <?php # Script 11.5 - loggedin.php ob_start(); ?> 

Script 11.5. This very simple version of loggedin.php makes use of output buffering and sessions.


2.

Create the HTML header.

 <!DOCTYPE html PUBLIC "-//W3C//DTD  XHTML 1.0 Transitional//EN "http://www.w3.org/TR/xhtml1/DTD/  xhtml1-transitional.dtd> <html xmlns="http://www.w3.org/1999/  xhtml xml:lang="en" lang="en"> <head>   <meta http-equiv="content-type"    content="text/html; charset=    iso-8859-1 />   <title>Logged In!</title> </head> <body> 

3.

Start a session and see if the user is logged in.

 <?php session_start(); if (isset($_SESSION['first_name']) ) {   echo "<p>You are now logged in,    {$_SESSION['first_name]}.</p>"; 

Similar to previous scripts, this page will check for the presence of a specific session variable as verification that the user is logged in. If so, they'll be greeted by name.

4.

Redirect the user if they are not logged in.

 } else {   ob_end_clean();   $url = 'http://' . $_SERVER    ['HTTP_HOST] . dirname($_SERVER    ['PHP_SELF]);   if ((substr($url, -1) == '/') OR    (substr($url, -1) == '\\') ) {      $url = substr ($url, 0, -1);   }   $url .= '/login.php';   header("Location: $url");   exit(); } 

This code mimics that in login.php, redirecting the user back to that page should they not already be logged in.

5.

Finish the page.

 echo '</body> </html>'; ob_end_flush(); ?> 

6.

Save the page as loggedin.php, upload to your Web server (in the same directory as login.php), and test in your Web browser (Figures 11.15 and 11.16).

Figure 11.15. If the user is logged in, they'll be greeted by their first name.


Figure 11.16. Anyone who attempts to access the loggedin.php page without first logging in will be redirected back to login.php.


Tips

  • The maximum buffer size can be set in the php.ini file. The default is 4,096 characters.

  • As of PHP 4.0.4, you can send compressed output to browsers by starting output control with ob_start('ob_gzhandler'), minimizing the download size of your pages. The ob_gzhandler() function will determine the appropriate type of compression to use (gzip, deflate, or none) depending upon what the browser can accept. Understand that compression is beneficial only on larger Web pages, and to use it, the output_buffering setting in the php.ini file must be set to Off.

  • The ob_get_length() function returns the length (in number of characters) of the current buffer.

  • The ob_get_contents() function will return the current buffer so that it may be assigned to a variable, should the need arise.

  • The ob_flush() functionnew as of PHP 4.2will send the current contents of the buffer to the Web browser and then discard them, allowing a new buffer to be started. This function allows your scripts to maintain more moderate buffer sizes.

  • The ob_clean() functionalso new as of PHP 4.2deletes the current contents of the buffer without stopping the buffer process.

  • PHP will automatically run ob_end_flush() at the conclusion of a script if it is not otherwise done.




    PHP and MySQL for Dynamic Web Sites. Visual QuickPro Guide
    PHP and MySQL for Dynamic Web Sites: Visual QuickPro Guide (2nd Edition)
    ISBN: 0321336577
    EAN: 2147483647
    Year: 2005
    Pages: 166
    Authors: Larry Ullman

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net