脚本重定向后会执行PHP脚本吗?

时间:2013-02-13 05:31:49

标签: php

是的,之前已经问过这个问题,但答案却不一致。以Why I have to call 'exit' after redirection through header('Location..') in PHP?为例。每个答案(包括接受的答案)都是肯定的,除了收到零票的最后一个答案,表示“可能”。我开始认为正确的答案是“可能”。为了使它成为一个简单的“是”或“否”问题,将在给定以下脚本的情况下执行这个()吗?感谢

header('Location: http://somewhereElse.com');
//die();
sleep(1000);
doThis();

EDIT 谢谢,所有。使用我的PHP / Linux / Apache配置,第二个syslog()执行,所以答案是“是的,将执行标题的所有脚本下游”。我将假设(并希望我是正确的)它与所有PHP / Linux / Apache配置相同!

<?php
  header('Location: http://google.com');
  syslog(LOG_INFO,'first');  
  sleep(5);
  syslog(LOG_INFO,'Second');  
?>

10 个答案:

答案 0 :(得分:21)

是的,如果你没有明确地终止它,脚本会在调用header('Location: http://google.com')后继续处理!我刚在当地尝试过。我使用以下内容将test.php添加到apache中的站点:

<?php

header('Location: http://google.com');
error_log("WE MADE IT HERE SOMEHOW");

?>

并检查了我的/ var / log / apache2 / error_log以获取此条目:

[Tue Feb 12 23:39:23 2013] [error] [client 127.0.0.1] WE MADE IT HERE SOMEHOW

可能令人惊讶,但是,如果你不停止执行,它会继续执行。

答案 1 :(得分:7)

人们似乎对此非常困惑,以及脚本执行的原因。 当您发送重定向标题时,浏览器会立即将用户重定向到新页面,但即使最后没有人接收代码,您的服务器也会继续处理代码,这并不意味着脚本已终止。除非您将Apache配置为在实现时停止脚本,否则在另一端没有人。

当PHP脚本正常运行时,NORMAL状态处于活动状态。如果远程客户端断开连接,则打开ABORTED状态标志。远程客户端断开通常是由用户按下STOP按钮引起的。

  

您可以决定是否要让客户端断开连接   你的脚本要中止。有时总是有你的方便   即使没有远程浏览器接收,脚本也会运行完成   输出。但是,您的脚本的默认行为是   远程客户端断开连接时中止。可以设置此行为   通过ignore_user_abort php.ini指令以及通过   对应的php_value ignore_user_abort Apache httpd.conf指令   或使用ignore_user_abort()功能。

在没有进一步操作的情况下重定向用户的正确方法是:

header("Location: blah.php");
exit();

答案 2 :(得分:5)

让我解释一下。我们有一个使用session的例子。

$_SESSION["username"] = 'some username';
header("Location: another-file.php");
$_SESSION["username"] = 'replace username';

$_SESSION["username"]的结果为replace username

您可以输出比标题Location标题更多的标题,其中大部分都不想停止代码执行。如果要停止代码执行,则需要明确调用exit

header命令不会中断代码流。即使遇到这种情况,浏览器仍然会下载您的页面,即使它没有显示。考虑404 pages,它(尽管是错误的)仍然由浏览器处理(尽管它们在重定向时不会被渲染)。

答案 3 :(得分:3)

运行代码:

//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);

在客户端重定向我之前,服务器暂停并写入文件。这是因为,即使在flush()缓冲区之后,在脚本停止执行(即脚本终止)之前,不会处理重定向。文件test.txt在每种情况下都有'1' ,这意味着标题已被发送,直到连接终止才被浏览器处理。

  • 在每种情况下,意思是在win32开发机器,linux开发机器和linux生产环境中。

答案 4 :(得分:2)

第一个示例显示某些代码在标头位置重定向之后执行,但并非所有代码都必须执行。一旦浏览器开始响应重定向标头,它就会终止当前页面上的连接,这将导致PHP终止执行其代码。这表明不怎么做。

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

在这个例子中,我添加了ignore_user_abort()来展示如何执行所有代码:

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!

这就是你通常通过在重定向后立即终止脚本来执行重定向的方法:

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

简而言之,要么使用die(),exit()或ignore_user_abort(TRUE);

答案 5 :(得分:0)

是的,它会在很短的时间内执行。

  

一旦重定向标题发送到浏览器,浏览器就会   关闭当前连接并为重定向URL打开一个新连接。   直到原始连接关闭,Apache关闭   脚本,您的代码将继续像以前一样执行。

     

理论上,如果之间有足够快的连接   客户端/服务器,管道中的任何地方都没有缓冲,   发出标题会导致脚本被终止   立即。实际上,它可以介于&#34;现在&#34;并且&#34;从不&#34;   关闭启动。

Read more

答案 6 :(得分:0)

是是是的,标题就像php脚本的任何其他部分一样,它将在脚本执行完成后发送,但诀窍是:如果我们想重定向到新的URL:那么为什么在标题之后继续执行脚本(“location:url”); ?&GT;

<?php
header('Location: test.php');
header('Location: test.php');
header('Location: test.php');
header('Location: test.php');
header('Location: test.php');
header('Location: test.php');
header('Location: test.php');

$var = 'google.com';
header("Location: http://$var");

?> 

答案 7 :(得分:0)

header("Location: http://example.com/newURL.php");
die;

是的,脚本重定向后脚本会继续,因此请确保在重定向到停止执行时随时调用die;exit;。不要让脚本睡觉:)。

How to make a redirect in PHP?

答案 8 :(得分:0)

重定向完成后,脚本仍将运行。尽管有时可能有用,但是使用header函数的人必须意识到,这样做可能很危险。看看这段非常不安全的代码:

<?php
if($_GET['some_secret'] != '123') {
    setcookie("status", "not logged in");
    header("Location: /");
}
setcookie("status", "logged in");

echo("Some secret info!")
?>

无论您输入什么 some_secret ,您将始终拥有一个值为已登录的cookie。唯一的区别是,如果给出错误的参数值,用户将被重定向。

解决方案:使用die()exit()方法在重定向后立即结束脚本

此较小的更正将使我们的脚本按我们希望的那样工作。

<?php
if($_GET['some_secret'] != '123') {
    setcookie("status", "not logged in");
    header("Location: /");
    die();
}
setcookie("status", "logged in");

echo("Some secret info!")
?>

(我不会用else语句显示另一个简单的解决方案,因为这实际上并不是应该采用的方法。)


您可能会认为,至少用户不会在屏幕上看到您打印的机密信息。 错误!浏览器只是进行重定向,但是我们要遵循它。

在此示例中,我使用了没有die的易受攻击的代码:

$ telnet 192.168.1.39 80
Trying 192.168.1.39...
Connected to 192.168.1.39.
Escape character is '^]'.
GET /test.php?some_secret=wrong
Some secret info!
Connection closed by foreign host.

如您所见,秘密信息泄漏了。

因此请注意,header可能非常不安全!
...并且请记住,通常不要以明文形式存储密码之类的数据或以cookie登录的信息之类的信息

答案 9 :(得分:-1)

USECASE SCENARIO:将用户重定向到强制门户,然后启动倒数计时器,在x分钟后将其写入阻止列表。