Yes, this question has been asked before, however, the answers have been inconsistent. Take Why I have to call 'exit' after redirection through header('Location
People seem to get this really confused, and as to why the script is executed. When you send the redirect header the browser immediately redirects the user to the new page but your server will continue to process the code even though there is no one to receive it at the end, this doesn't mean the script is terminated. Unless you configure Apache to stop the script when it realizes there is no one on the other end.
When a PHP script is running normally the NORMAL state, is active. If the remote client disconnects the ABORTED state flag is turned on. A remote client disconnect is usually caused by the user hitting his STOP button.
You can decide whether or not you want a client disconnect to cause your script to be aborted. Sometimes it is handy to always have your scripts run to completion even if there is no remote browser receiving the output. The default behaviour is however for your script to be aborted when the remote client disconnects. This behavior can be set via the
ignore_user_abort
php.ini directive as well as through the corresponding php_valueignore_user_abort
Apache httpd.conf directive or with theignore_user_abort()
function.
The correct way of redirecting a user without further actions is:
header("Location: blah.php");
exit();
header("Location: http://example.com/newURL.php");
die;
Yes the script continues after the header redirect, so make sure to call die;
or exit;
any time you you redirect to stop execution. Don't need to put the script to sleep :).
How to make a redirect in PHP?
Running the code:
//http://www.php.net/manual/en/function.header.php
header('Location: http://google.com');
flush();
sleep(3);
$a=fopen('test.txt', 'w');
fwrite($a,headers_sent());
fclose($a);
The server paused and wrote the file before the client redirected me. This is because, even after flush()
ing the buffer, the the redirect is not processed until the script ceases execution (ie, the script terminated). The file test.txt
had '1' in every case, meaning that the headers were sent, just not processed by the browser until the connection was terminated.
Yes, the script continues to process after the call to header('Location: http://google.com')
if you don't explicitly terminate it! I just tried this locally. I added test.php to a site in apache with these contents:
<?php
header('Location: http://google.com');
error_log("WE MADE IT HERE SOMEHOW");
?>
And checked my /var/log/apache2/error_log for this entry:
[Tue Feb 12 23:39:23 2013] [error] [client 127.0.0.1] WE MADE IT HERE SOMEHOW
Possibly surprising, but yes, it continues to execute if you don't halt execution.
Let me explain more. let's have an example using session.
$_SESSION["username"] = 'some username';
header("Location: another-file.php");
$_SESSION["username"] = 'replace username';
Result of $_SESSION["username"]
will be replace username
You can output a lot more headers than just Location
headers with header, most of which you don't want to stop your code execution. If you want to stop code execution, you need to call exit
explicitly.
The header
command doesn't interrupt the flow of your code. Even if that is encountered, your page is still downloaded by the browser, even if it isn't show. Consider 404 pages
, which (despite being errors) are still processed by the browser (though they are rendered while redirects are not).
This first example shows that some code is executed after the header location redirect, but that not all code is necessarily executed. Once the browser starts responding to the redirect header, it'll terminate the connection on the current page, which will causes PHP to terminate executing its code. This shows how NOT to do things.
session_start();
$_SESSION["some_value"] = 'original value';
header("Location: /index.php/test2");
$start_time = microtime(true);
for($i = 0; $i <= 100000; $i ++)
{
password_hash($i); // slow it down
$_SESSION["some_value"] = $i;
$_SESSION['time'] = microtime(true) - $start_time;
}
$_SESSION['some_value'] = 'finished!';
// Result:
// some_value = 174
In this example I added ignore_user_abort() to show how to execute all the code:
ignore_user_abort(TRUE);
session_start();
$_SESSION["some_value"] = 'original value';
header("Location: /index.php/test2");
$start_time = microtime(true);
for($i = 0; $i <= 100000; $i ++)
{
password_hash($i); // slow it down
$_SESSION["some_value"] = $i;
$_SESSION['time'] = microtime(true) - $start_time;
}
$_SESSION['some_value'] = 'finished!';
// Result:
// some_value = finished!
And this is how you would typically execute a redirect, by killing the script immediately after the redirect:
session_start();
$_SESSION["some_value"] = 'original value';
header("Location: /index.php/test2");
die();
$start_time = microtime(true);
for($i = 0; $i <= 100000; $i ++)
{
password_hash($i); // slow it down
$_SESSION["some_value"] = $i;
$_SESSION['time'] = microtime(true) - $start_time;
}
$_SESSION['some_value'] = 'finished!';
// Result:
// some_value = original value
In short, either use die(), exit(), or ignore_user_abort(TRUE);