David has posted 35 posts at DZone. You can read more from them at their website. View Full User Profile

PHP Redirect Function

03.01.2008
| 87254 views |
  • submit to reddit

After form submission or a page redirect is triggered, it's commonplace to redirect the user to a different page or to the same page, formatted in a different way. Usually, you'd complete this by coding:

header('Location:  destination.php');
exit();

This is a completely acceptable way to code your pages, but I prefer to use a redirect function instead. Why? It's much more readable, and quite honestly, I'm tired of writing the header('Location: …') code.

function redirect($url,$permanent = false)
{
if($permanent)
{
header('HTTP/1.1 301 Moved Permanently');
}
header('Location: '.$url);
exit();
}

Do you have any suggestions for improvement?

References
Published at DZone with permission of its author, David Walsh. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:

Comments

David Walsh replied on Mon, 2008/03/03 - 9:00am

Thank you for the tip Amir!

Loïc Hoguin replied on Tue, 2008/03/04 - 9:16pm

Filter the input directly in this function so you can send anything without worrying and you're good.

Francesc Rosàs replied on Wed, 2008/03/05 - 6:47pm

The one I use is pretty much the same but makes sure the URL is absolute (as required by the RFC) and fixes a strange design bug about fragments (I don't remember what solves exactly but I needed it once).

I still don't like that "exit" but is more convenient.

BTW, is session_write_close() really needed?


static function redirect ($url)
{
$url = Common_Url::create($url)->toAbsolute();

// Bug fix for http://www.w3.org/Protocols/HTTP/Fragment/draft-bos-http-redirect-00.txt
if ($url->equals(Common_Url::getCurrent()->setFragment(''))) {
$url->setFragment('redirect-fragment-bugfix');
}

header('Location: ' . $url);
exit;
}

Billy Bigwilly replied on Fri, 2008/03/14 - 5:04pm

I think a header Location redirect is an awkward way to force people into a direction. Even after a form submission there are more gentle ways to do that.

I would say: avoid this kind of redirects all together. Why? Because it is another request on your server. If you can't handle the request at once, why redirect it?

Do something like this (pseudocode):

if (GET || POST)

handle submitted information

show result page (instead of redirect, show it here directly, saves another request)

else

show form

endif

It sounds strange, but another request implicates loading the libraries again, loading stylesheets and templates again etc.

 

Michael Sharman replied on Sat, 2008/05/03 - 12:12am

@David - I'm new to PHP (coming from other server side web languages though) and not sure I understand the need for exit();

header('Location: '.$url);
exit();


If you are already doing a redirect (using header) then why exit the script? Will it not exit automatically as you're redirecting?

Sorry if that's a silly qestion!

Update: Hmm, after reading the docs at php.net it seems you really do need to exit() after calling header(). Still not sure why though if it's a server redirect.

Amir Laher replied on Sat, 2008/05/03 - 3:40am

it's a client-side redirect.

The header function deals with HTTP response headers so the server script will not deal with it much differently than any other header. The script will just run its natural course. You'll never see the output in the browser because your browser will simply follow the redirect and ignore the output.

You can see for yourself by setting up a small script, then using telnet from a command prompt

 Example script redirect-script.php (in your document root):

<?php
header('Location: http://www.google.com/');
echo "private stuff\n";
?>

Telnet test:

Type the following from a dos or unix command prompt:

 telnet yourservername.com 80

(Personally I'm using localhost. It'll say something about your server)

Now type in the following HTTP request header, followed by 2 carriage returns:

 GET /redirect-script.php HTTP/1.0

 

(you need to press enter twice before the server knows you're finished)

It should output something like this ... 

HTTP/1.1 302 Found
Date: Sat, 03 May 2008 08:26:59 GMT
Server: Apache/2.2.8 (Ubuntu) PHP/5.2.4-2ubuntu5 with Suhosin-Patch
X-Powered-By: PHP/5.2.4-2ubuntu5
Location: http://www.google.com/
Content-Length: 14
Connection: close
Content-Type: text/html

private stuff
Connection closed by foreign host.

 

As you can see it still executes the private stuff, whether it be unauthorised data manipulation or just printing top-secret information back in the response. One other thing to note is that PHP cleverly realises it needs to set the HTTP response code to 302 (rather than 200 OK)

hth

 Amir

Victor Caravaca replied on Fri, 2008/05/16 - 2:21pm

hi... I got a problem with the header.... my code is....

<?php

include "conexion.php";  //llama a conectar a BD

$result = mysql_query("select usuario, pass from t_usuario where usuario = '$usuario' and pass = '$pass'", $conexion);
if(mysql_num_rows($result)>0){  
    header( "Location: http://www.solucionesclimaticascr.com/ingreso.html" ); 
    exit; 
  } else {
  echo "No le es permitido ingresar a esta &aacute;rea, es restringida";
 
 }
  
include "cerrar_conexion.php";
?>

it doesn't work the header.... don't call the page.... now if I use this one:

<?php

include "conexion.php";  //llama a conectar a BD

$result = mysql_query("select usuario, pass from t_usuario where usuario = '$usuario' and pass = '$pass'", $conexion);
if(mysql_num_rows($result)>0){   
  echo "<td>Su ingreso es satisfactorio! </td> \n";
  //echo "<td> </td> \n";
  echo "<td><a href='lista_usuarios_noticias.php', 'mainFrame'>Ingrese ac&aacute; para administrar listado de personas inscritas en Newsletter.</a></td> \n";
   } else {
  echo "No le es permitido ingresar a esta &aacute;rea, es restringida";
 
 }
  
include "cerrar_conexion.php";
?>

 it works... but i don't need display the link... i need if >0 go to page ... ingreso.html and display it on the mainframe cause my page has frames (top and mainframe)

where is my error?

 

tnks

Jesse Marple replied on Wed, 2008/05/21 - 8:57am

I'm having the same issue as as viccowface.  I'm learning PHP and have arrived at a point where I have to update some information in the database.  When that's successful I'd like to redirect back to a page.  Here's my code:

<?php require_once("includes/connection.php");?>

<?php require_once("includes/functions.php");?>

<?php

$menu_name = $_POST['menu_name'];

$position = $_POST['position'];

$visible = $_POST['visible'];

?>

<?php $query = "INSERT INTO subjects (

menu_name, position, visible

) VALUES (

'{$menu_name}', {$position}, {$visible}

)";

if (mysql_query($query, $connection)) {

// SUCCESS!

header("location: content.php");

exit;

} else {

//Display error message.

echo "<p>Subject creation failed.</p>";

echo "<p>" . mysql_error() . "</p>";

}?>

<?php mysql_close($connection)?> 

 I've employed the tip at the top of this post but I still get the header error that I : Cannot modify header information - headers already sent. 

I've read that PHP 5+ doesn't allow for headers to be resent to avoid an injection threat.  How can I redirect people after successfully completing the upload to the database if I can't use HEADER?

 Any help would be greatly appreciated.  I'm stuck here. 

Ali Rashid replied on Wed, 2008/05/21 - 9:42pm in response to: Amir Laher

Hey guys!

Those of you who are wondering about the header and why it executes the lines after it, well apparantly Amir is right, PHP will execute all the commands after header and then redirect. You need to use exit() but that will not clear the resources on the server. This is especially necessary if you are redirecting to another server / website. For that, use die() so that the site clears all the resources. It will look something like this:

header ('Location:'.$URL) ;
die();

Remember that when you use the syntax above, then you cannot use any type of print statements before it else you get the error, headers already sent or something like that. The basic culprits for this error are print, echo or html tags. there are 2 ways to by pass this issue, either declare a redirect function on the top of the page and call that whenever you need to redirect but a more stable way is to use "ob" functions. Something like:

ob_start();
echo "Who Who Ha Ha! Blah Blah Bling!";
header ('Location:'.$URL);
ob_flush();

That should do the trick. Hope that this helps some innocent soul from not spending hours on figuring out what they need to do.
Regards,
Ali

arung palaka replied on Fri, 2010/11/26 - 4:57am

hello guys

In my case, I want to present a simple PHP script to set up a PHP redirect page and I used header() function to redirect a PHP page to another web page.

<?
Header( "HTTP/1.1 301 Moved Permanently" );
Header( "Location: http://www.domain.com/redirect-to-new-page.php" );
die();
?>
To do a temporary redirect (302 redirect), add “HTTP/1.1 302 Moved Temporarily” to the first header function, in the above script.

otherwise you may get a warning message as below:

Warning: Cannot modify header information - headers already sent by

However you can put this code to avoid the above warning massage like this
<?
php ob_start();
echo "Hello!!!";
header("Location: http://www.domain.com/redirect-to-new-page.php");
ob_flush();
?>
 That's all Thanks, Lucky PHP Developer



 


 

Roman Dot Net F... replied on Thu, 2011/10/06 - 9:12pm

Hello!
Nice post! I'd like to note that there are at least two more ways to make the redirect, especially if headers are already sent: Meta refresh and JavaScript redirect. I described them wider in my article here - PHP: Redirection Overview.
Thank you!

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.