header("Location: ...")之后的代码会执行吗?

28
$_SESSION["some_value"] = 4;
header("Location: another-file.php");
$_SESSION["some_value"] = 5;

$_SESSION["some_value"]的值是什么?

5个回答

27

这个值是5。

你可以使用header输出许多不止是Location头部的头部信息,大多数情况下你不想停止代码执行。如果你需要停止代码执行,你需要显式调用exit函数。


11

在重定向之后,你应该始终使用die()或exit()(或者根据Mark B的指示使用ignore_user_abort()),因为否则你无法确定会发生什么。

尽管在header location重定向后有些代码将被执行,但重要的是要注意,并非所有代码都一定会得到执行。

就你的例子而言,是的,some_value将等于5。但在某个时候,脚本将会被过早地终止。

请看以下例子:

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!';
如果其他答案都正确,你会认为 $_SESSION['some_value'] 等于 'finished!' -- 但是我运行了代码,情况并非如此。
以下是我的结果:
some_value: 174
time: 0.0026998519897461

第二次试验:

some_value: 218
time: 0.0033109188079834

第三次试验:

some_value: 218
time: 0.0035371780395508

第四次试验:

some_value: 174
time: 0.0026431083679199

第五个试验:

some_value: 174
time: 0.0027921199798584
如果我在上面的脚本中实现ignore_user_abort(TRUE);,那么some_value确实等于"finished!",所以如果你打算在重定向之后执行一些关键操作,例如日志记录、数据库查询或发送电子邮件,请记住这一点。

1
一个优秀而且非常有信息量的答案——如果只有更多的人能像这样回答问题。我现在已经接受了它,取代之前被接受的答案(我希望发帖者不会介意;毕竟他不需要这些分数 ;-)。谢谢 - Mawg says reinstate Monica

5
一旦你发出头部信息,你就启动了代码和web服务器/浏览器之间的竞赛。通常情况下,一旦浏览器接收到重定向信息,它会关闭运行脚本的连接并开始连接到新的重定向URL。当连接关闭时,Web服务器通常会尝试终止脚本。你可能会很幸运,能够完成其他想做的事情,或者你可能会不幸,脚本甚至无法到达header()调用后的下一行。
有一个函数叫做ignore_user_abort(),可以让你的脚本无论连接状态如何都能继续执行。

1
不,即使有位置头信息,它仍会下载整个响应。这就是为什么如果你想要重定向而不执行任何其他代码,你需要在头信息后调用 exit;。如果剩余的代码是否执行是随机的,那么这将不是一个非常有用的功能,对吧? - Tor Valamo
它不应该是一项功能,只是一个有趣的小漏洞,提醒你浏览器的工作方式。当然,它们并不是这样的。 - muhmuhten
@TorValamo 我不确定那完全准确。我一直在一个项目上工作,在其中我设置了位置头而没有退出,本地代码后面没有执行,但是当它被推到开发服务器进行测试时,代码正在被执行! - billyonecan
1
@billyonecan 我相信这与 PHP 引擎的配置有关。当你确实需要限制时,最好选择限制性选项,而不是希望开发服务器已经有了限制。 - Tor Valamo

2
< p > header 命令不会中断您的代码流程。即使遇到它,浏览器仍会下载您的页面,即使它没有显示。考虑 404 页面,尽管它们是错误页面,但仍然会被浏览器处理(尽管重定向时不会呈现)。< /p >

1
当然是5。在这样的头文件后面必须加上exit()。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接