Output Buffering

Output control (or output buffering) allows you to write and execute your scripts normally but send data to the web browser at selected times. The main benefit of this system is that you can call the header(), setcookie() and session_start() functions at any place in your scripts without having to worry about the "headers already sent" error message.

The tools

In our battle against the "headers already sent" error message, we are going to use several functions that are natively available to PHP:

header()-is used to send a raw HTTP header.

Syntax - ( string $string [, bool $replace [, int $http_response_code]] )

setcookie() – defines a cookie to be sent along with the rest of the HTTP headers. Like other headers, cookies must be sent before any output from your script (this is a protocol restriction). This requires that you place calls to this function prior to any output, including <html> and <head> tags as well as any whitespace.

Syntax - ( string $name [, string $value [, int $expire [, string $path [, string $domain [, bool $secure [, bool $httponly]]]]]] )

session_start() – creates a session or resumes the current one based on the current session id that’s being passed via a request, such as GET, POST, or a cookie.

Syntax – session_start()

ob_start()- This function will turn output buffering on. While output buffering is active, no output is sent from the script (other than headers). Instead, the output is stored in an internal buffer.

Syntax – ob_start()

ob_end_flush() – This function will send the contents of the topmost output buffer (if any) and turn this output buffer off. If you want to further process the buffer’s contents you have to call ob_get_contents() before ob_end_flush() as the buffer contents are discarded after ob_end_flush() is called.

Syntax – ob_end_flush()

ob_end_clean() – This function discards the contents of the topmost output buffer and turns off this output buffering. If you want to further process the buffer’s contents you have to call ob_get_contents() before ob_end_clean() as the buffer contents are discarded when ob_end_clean() is called.

Syntax – ob_end_clean()

{mospagebreak title=Login Script}

We’ll use a login script to demonstrate how to use these functions. Below is the code:


<?php

ob_start();

session_start();

//database connection details:

$title = "My Application Title";

$version = "3.0";


//database connection

$bdhost="localhost";

$dbuser="root";

$dbpass="pass";

$dbname="users";


$db = mysql_connect($dbhost,$dbuser,$dbpass) or die("Failed to open connection to MySQL server.");

mysql_select_db($db) or die("Unable to select database");


//set useful variables

$month_names = array("","January","February","March","April","May","June","July","August",
"September","October","November","December");


//set useful variables

$td = date("Y-m-d");

$date_time =date("Y-m-d h:i:s");

//someone registered?

if(isset($_GET['reg'])){

$reg="Your details have been added, please login";

}

$error=false;

$errmsg="";


//has form been submitted

if(isset($_POST['key'])){


//check that the username and password is not empty

if( empty($_POST['uname']) && (empty($_POST['upass']))){

print "Please enter your username and password.";

$errmsg="Please enter your username and password.";

$error=true;

}


//check that the username and password is string

if( is_numeric($_POST['uname']) && (is_numeric($_POST['upass']))){

print "Please enter a valid username and password.";

$errmsg=" Please enter a valid username and password.";

$error=true;

}



//if no error then start authentication process

if(!$error){


//transfer to shorter var

$n=$_POST['uname'];

$p=$_POST['upass'];



//clean using mysql cleaner

$cleanuname=mysql_real_escape_string($n);

$cleanupass=mysql_real_escape_string($p);

$query="select uname,pw from users where uname=’$cleanuname’ and pw=’$cleanupass’ ";

$result=mysql_query($query);


$num=mysql_num_rows($result);

if($num>0 ){


//put in session vars

session_start();

$mytime=time();

$mytime=date("H:i:s A",$mytime);

$_SESSION['time'] = $mytime;

$_SESSION['status'] = ‘logged';

$_SESSION['username'] = $cleanuname;

//goto next page

header("location:welcome.php");

exit;

}

}else{

$_SESSION['status'] = ‘not logged';

$errmsg="Your username ($n) and password do not match, please try again.";

}

}

?>



<!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"><!– InstanceBegin template="/Templates/was.dwt.php" codeOutsideHTMLIsLocked="false" –>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />

<!– InstanceBeginEditable name="doctitle" –>

<title>WebSecure::Login</title>


<script language="javascript" type="text/javascript">

function checkform(pform1){

if(pform1.uname.value==""){

alert("Please enter a username")

pform1.uname.focus()

return false

}


if(pform1.pw.value==""){

alert("Please enter a password")

pform1.pw.focus()

return false

}


if(pform1.pw.value=="" && pform1.uname.value==""){

alert("Please make sure that you have entered your username and password")

return false

}

return true

}

</script>

<!– InstanceEndEditable –>

<!– InstanceBeginEditable name="head" –>

<!– InstanceEndEditable –>

<link href="../Templates/was.css" rel="stylesheet" type="text/css" />

</head>


<body>

<table width="99%" border="1">

<tr>

<td bgcolor="#333333" class="header">Web Secure</td>

</tr>



<tr>

<td><!– InstanceBeginEditable name="main" –>

<form name="form1" method="post" action="" onSubmit="return checkform(this)">

<table width="41%" border="0" align="center" cellpadding="0" cellspacing="3">

<tr class="listtop">

<td colspan="3">Login Status:<? if(isset($errmsg)){

echo "$errmsg";

}elseif(isset($reg)){

echo "$reg";

}?></td>

</tr>

<tr>

<td width="9%">Username</td>

<td width="41%"><input name="uname" type="text" id="uname" size="50"></td>

<td width="50%" rowspan="4">&nbsp;</td>

</tr>

<tr>

<td>Password</td>

<td><input name="upass" type="password" id="upass" size="50">

<input type="hidden" name="key" /></td>

</tr>

<tr>

<td>&nbsp;</td>

<td><a href="../password.php">Forgotten your password?</a>|<a href="register.php">Register</a></td>

</tr>

<tr>

<td>&nbsp;</td>

<td><input type="submit" name="submit" value="Login"></td>

</tr>

</table>

</form>

<!– InstanceEndEditable –></td>

</tr>

<tr>

<td class="copy">&copy;2008</td>

</tr>

</table>

</body>

<!– InstanceEnd –></html>

<? ob_end_flush(); ?>

{mospagebreak title=Code Explained}

Notice that I’ve highlighted the functions that are used for output buffering. To begin output buffering, we use the ob_start() function, which is located at the very top of the page:


<?

ob_start();

session_start();


//someone registered?

if(isset($_GET['reg'])){

$reg="Your details have been added, please login";

}

$error=false;

$errmsg="";


//has form been submitted

if(isset($_POST['key'])){

//check that the username and password is not empty

if( empty($_POST['uname']) && (empty($_POST['upass']))){

print "Please enter your username and password.";

$errmsg="Please enter your username and password.";


Once you’ve called the ob_start() function, every single output for this page will be sent to a memory buffer rather than to the web browser. HTTP calls, like the header() and setcookie(), won’t be buffered and will operate as usual.

Towards the end of the script you will notice the ob_end_flush() function:

<tr>

<td>&nbsp;</td>

<td><input type="submit" name="submit" value="Login"></td>

</tr>

</table>

</form>

<!– InstanceEndEditable –></td>

</tr>

<tr>

<td class="copy">&copy;2008</td>

</tr>

</table>

</body>

<!– InstanceEnd –></html>

<? ob_end_flush(); ?>


This function will take the accumulated buffer and send it to the web browser. You can also use the ob_end_clean() function; it does the same thing. Both of the functions turn off output buffering.

From a developer’s point of view, there is not so much of a benefit except that once you start using these functions, you really don’t have to spend any time worrying about HTTP headers. When you use templates in your applications, it would be beneficial to place these functions at the top (ob_start() and ob_end_flush() at the bottom). That way, these functions will be available on every page of your site.

{mospagebreak title=Further suggestions}

You can set the maximum buffer size in your PHP configuration file. The default is 4096 characters. Below is an extract from a PHP configuration file, showing the default setting:


; – log_errors = On [Security]

; This directive complements the above one. Any errors that occur during the

; execution of your script will be logged (typically, to your server’s error log,

; but can be configured in several ways). Along with setting display_errors to off,

; this setup gives you the ability to fully understand what may have gone wrong,

; without exposing any sensitive information to remote users.

; – output_buffering = 4096 [Performance]

; Set a 4KB output buffer. Enabling output buffering typically results in less

; writes, and sometimes less packets sent on the wire, which can often lead to

; better performance. The gain this directive actually yields greatly depends

; on which Web server you’re working with, and what kind of scripts you’re using.




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 determines the appropriate type of compression to use (gzip,deflate, or none) based on what the browser can accept. Compression is beneficial only on larger web pages, and in order 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 of the current buffer contents.

<!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">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />

<title>Untitled Document</title>

</head>


<body>


<?php


ob_start();


echo "Go for it ";


$oblength1 = ob_get_length();


echo "World";


$oblength2= ob_get_length();


ob_end_clean();


echo $oblength1 . ", ." . $oblength2;

var_dump($oblength1, $oblength2);

?>


</body>

</html>


The above code outputs the following:

10, .15

int(10)

int(15)

The ob_get_contents() function returns the current buffer so that it can be assigned to a variable if needed:


<!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">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />

<title>Untitled Document</title>

</head>


<body>


<?php


ob_start();


echo "My name is David Web ";


$obcontents1 = ob_get_contents();


echo "and i’m very tired right now";


$obcontents2 = ob_get_contents();


ob_end_clean();


var_dump($obcontents1, $obcontents2);

?>


</body>

</html>


The code above outputs:

string(21) "My name is David Web "

string(49) "My name is David Web and i’m very tired right now"

PHP automatically runs the ob_end_flush() function at the end of a script if it is not otherwise called. But it is better to get into the habit of calling it yourself.

[gp-comments width="770" linklove="off" ]
antalya escort bayan antalya escort bayan