简体   繁体   English

发送标头('Location:…')命令后,PHP脚本将处理多长时间?

[英]How long after sending a header('Location: …') command will the PHP script process?

I have two PHP scripts which both have an "include_once('authentication.inc');" 我有两个PHP脚本,每个脚本都有一个“ include_once('authentication.inc');”。 script near the top. 脚本靠近顶部。 Both scripts reference the same authentication file. 这两个脚本都引用相同的身份验证文件。 That authentication file currently performs a header redirect (like "header('Location: index.php');") if the user is not signed in. 如果用户未登录,则该身份验证文件当前执行标头重定向(例如“ header('Location:index.php');”)。

In one file (A.php) the immediate next line of code after the include of the authentication file is: 在一个文件(A.php)中,包含身份验证文件之后的直接下一行代码是:

if(isset($_GET['delete']))
   mysql_query("DELETE FROM table WHERE index=".$_GET['delete']);

In the other file (B.php) there are several other includes which occur before the same "delete code" listed above. 在另一个文件(B.php)中,还有其他几个包含在上面列出的相同“删除代码”之前的文件。

So the authenticate.inc file looks like: 因此authenticate.inc文件如下所示:

if(!valid_credentials($username,$password))
    header('Location: index.php');

And file A.php looks like: 文件A.php看起来像:

include_once('authenticate.inc');

if(isset($_GET['delete']))
   mysql_query("DELETE FROM table WHERE index=".$_GET['delete']);

And file B.php looks like: 文件B.php看起来像:

include_once('authenticate.inc');

include_once('other.php');
include_once('file2.php');
include_once('onemore.php');

if(isset($_GET['delete']))
   mysql_query("DELETE FROM table WHERE index=".$_GET['delete']);

Yet when I call A.php?delete=5, that record is deleted from the database while when I call B.php?delete=8 that record is not. 但是,当我调用A.php?delete = 5时,该记录将从数据库中删除,而当我调用B.php?delete = 8时,该记录却未被删除。

I have checked the 3 intermediary includes and do not see any die() statements, nor any other header redirects. 我已经检查了3个中介include,没有看到任何die()语句,也没有看到任何其他标头重定向。

So while it's clear that A.php is continuing to execute after the header is sent, why isn't B.php doing the same thing? 因此,很明显,在发送标头后A.php仍在继续执行,但B.php为什么不做同样的事情? Is the header being sent before the next set of imports? 标头是否在下一组导入之前发送?

** **

Also: I know to add the die() or exit command after the headers are sent. 另外:我知道要在发送标头后添加die()或退出命令。 I'm working on someone else's code and trying to explain behavior, not writing this myself. 我正在研究别人的代码,并试图解释行为,而不是自己写。

** **

No way to tell. 没办法说。 If the starts are aligned properly, the header coud be sent to the client browser immediately and the bowser will start closing the current connection and request the new URL immediately. 如果开始位置正确对齐,则标题将立即发送到客户端浏览器,并且Bowser将开始关闭当前连接并立即请求新的URL。 This'll cause the current PHP script to start shutting down. 这将导致当前的PHP脚本开始关闭。

On the other hand, if the caches are slow and the network glitchy, the client browser may not get the redirect header for seconds/minutes/hours, and the script could continue executing indefinitely. 另一方面,如果高速缓存很慢且网络出现故障,则客户端浏览器可能在几秒钟/几分钟/几小时内无法获得重定向标头,并且脚本可能会无限期地继续执行。

In general you should assume that the moment you've issued a header redirect that the script is basically "walking dead" and should not do any further work. 通常,您应该假定发出头重定向后,脚本基本上就已经“死了”,并且不应做任何进一步的工作。

The sole exception to this rule is that you CAN use ignore_user_abort(TRUE) , which tells PHP to NOT shut down when the remote user disconnects. 该规则的唯一例外是您可以使用ignore_user_abort(TRUE) ,它告诉PHP在远程用户断开连接时不要关闭。 That'd allow you to continue on working even though the browser has shut down the connection and moved on to the new page. 即使浏览器已关闭连接并移至新页面,您仍可以继续工作。

Update your authenticate.inc file to die() after the redirect. 重定向后,将authenticate.inc文件更新为die() This will prevent any other code from executing. 这将阻止执行任何其他代码。

if(!valid_credentials($username,$password)) {
    header('Location: index.php');
    die();
}

Without it, and depending upon your server configuration, the rest of the PHP code will be executed on the server even after the headers are transmitted back to the client. 没有它,并且取决于您的服务器配置,即使在标头传输回客户端之后,其余的PHP代码也会在服务器上执行。 Until the client closes the connection, the code will run. 在客户端关闭连接之前,代码将运行。

Just put an exit() after the header redirect. 只需在标头重定向后放置一个exit()即可。 It will stop all execution after the redirect. 重定向后它将停止所有执行。

There is probably some output in either of the included files, with echo or other outputting functions. 包含的文件之一中可能都有一些输出,带有echo或其他输出功能。 If the browser by then has followed the redirect and aborted the connection, the PHP script will by default exit. 如果那时浏览器遵循了重定向并中止了连接,则PHP脚本将默认退出。 You can change this behaviour with ignore_user_abort(true); 您可以使用ignore_user_abort(true);更改此行为ignore_user_abort(true); . You should however use die(); 但是,您应该使用die(); after the Location header. Location标头之后。 If the query execution is wanted, just put that query before the Location header. 如果要执行查询,只需将该查询放在Location标头之前。 Don't forget to use proper escaping for the input, otherwise the script could be a target for a mysql injection attack. 不要忘记对输入使用适当的转义,否则脚本可能成为mysql注入攻击的目标。

To answer your question, it seems that the browser will wait until your script finished execution and only then will request another location. 为了回答您的问题,浏览器似乎会等到脚本完成执行后才请求另一个位置。

Please note that you shouldn't use GET method to delete records. 请注意,您不应使用GET方法删除记录。

As for the not deleting id=8 - just debug it. 至于不删除id = 8-只是调试它。 Not a big deal. 没有大碍。
A good var_dump() is always better than some vague ideas about headers. 一个好的var_dump()总是比一些模糊的标题更好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM