浏览器退出时不会退出PHP脚本

时间:2011-07-14 19:24:45

标签: php termination

如果客户端关闭浏览器(因此连接到服务器),为什么这个虚拟脚本会继续运行事件?

while ( true )
{
    sleep( 1 );
    file_put_contents( '/tmp/foo' , "I'm alive ".getmypid()."\n" , FILE_APPEND );
}

根据this,我出乎意料。另外this示例似乎不起作用。

带有非零参数的set_time_limit根本无效。

我想澄清一下。

2 个答案:

答案 0 :(得分:9)

如果您尝试在该循环中将某些输出写入浏览器,则应该发现如果连接已终止,则脚本将中止。 ignore_user_abort

的文档中暗示了此行为
  

当运行PHP作为命令行脚本时,脚本的tty会运行   没有脚本被终止然后脚本将死亡   下次尝试写入任何内容时,除非将值设置为TRUE

我自己尝试了一些实验,发现即使您尝试某些浏览器输出,如果输出缓冲区尚未满,脚本也会继续运行。如果关闭输出缓冲,则在尝试输出时脚本将中止。这是有道理的 - SAPI层应该注意到请求在尝试传输输出时已经终止。

这是一个例子......

//ensure we're  not ignoring aborts..
ignore_user_abort(false);

//find out how big the output buffer is
$buffersize=max(1, ini_get('output_buffering'));


while (true)
{
    sleep( 1 );

    //ensure we fill the output buffer - if the user has aborted, then the script
    //will get aborted here
    echo str_repeat('*', $buffersize)."\n";

    file_put_contents( '/tmp/foo' , "I'm alive ".getmypid()."\n" , FILE_APPEND );
}

这表明触发中止的原因。如果你的脚本很容易进入一个无输出的无限循环,你可以使用connection_aborted()来测试连接是否仍然是打开的。

答案 1 :(得分:1)

set_time_limit仅限制在PHP代码中花费的时间。程序中的大部分时间(我猜是> 99.9%)花在系统调用,将数据写入文件和睡眠中。

ignore_user_abort仅在您将写入客户端(不在本地文件中)时才中止 - 在TCP中无法区分未使用和已终止的连接,除非客户端使用RST数据包激活地终止连接。