如果客户端关闭浏览器(因此连接到服务器),为什么这个虚拟脚本会继续运行事件?
而(真) { 睡眠(1); file_put_contents( '/tmp/foo' , "我还活着 ".getmypid()."\n" , FILE_APPEND ); }
而带有非零参数的set_time_limit根本什么都不做。
我想要一些澄清。
如果客户端关闭浏览器(因此连接到服务器),为什么这个虚拟脚本会继续运行事件?
而(真) { 睡眠(1); file_put_contents( '/tmp/foo' , "我还活着 ".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
仅当您向客户端(不在本地文件中)写入内容时才会中止 - 除非客户端明确终止与 RST 数据包的连接,否则您无法在 TCP 中区分未使用的连接和终止的连接。