为什么如果客户端关闭浏览器(因此连接到服务器),此虚拟脚本会继续运行事件?PHP脚本不会在浏览器退出时退出
while (true) { sleep(1); file_put_contents('/tmp/foo' , "I'm alive ".getmypid()."\n" , FILE_APPEND); }
而且带有非零参数的set_time_limit根本什么都不做。
我想澄清一下。
为什么如果客户端关闭浏览器(因此连接到服务器),此虚拟脚本会继续运行事件?PHP脚本不会在浏览器退出时退出
while (true) { sleep(1); file_put_contents('/tmp/foo' , "I'm alive ".getmypid()."\n" , FILE_APPEND); }
而且带有非零参数的set_time_limit根本什么都不做。
我想澄清一下。
如果您尝试在该循环中将一些输出写入浏览器,您应该发现如果连接已终止,脚本将中止。这种行为是在文档中暗示了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()来测试连接是否仍然打开。
set_time_limit
只限制花费在php代码上的时间。大部分时间(我猜测> 99.9%)在您的程序中花费在系统调用中,将数据写入文件并进行睡眠。
ignore_user_abort
只有当你(而不是在本地文件)写的东西到客户端中止 - 有根本没有办法可以在TCP区分未使用和终止的连接,否则,除非客户excplicitely终止连接与RST数据包。
您忽略了用户中止,而没有向客户端做任何输出。 – hakre