我正在用PHP做一个小实验。我有一个名为“finity.txt”的文件,在该文件中,我每0.25秒编写一个递增数。
while(true){
file_put_contents('infinity.txt', ++$i.PHP_EOL, FILE_APPEND);
usleep(250 * 1000);
}
这很好,但是当我关闭浏览器中的选项卡时,脚本继续运行。浏览器请求中止不是Ctrl. + C
,所以这并不奇怪,但我仍然在想,当用户断开连接时,是否可以中止无限循环,或者是否有任何方法来查看用户是否仍然连接。
顺便说一句,预先调用register_shutdown_function
是完全无用的,即使链接函数中有一个die()
。
更新:在我看来,使用connection_aborted()
函数可能会做一些事情。
更新2:我已经将代码更改为如下所示,但是遗憾的是,无限循环并没有取消:
while(true){
if(connection_aborted()){
file_put_contents('infinity.txt', 'CONNECTION ABORTED.', FILE_APPEND);
die();
}
file_put_contents('infinity.txt', ++$i.PHP_EOL, FILE_APPEND);
usleep(250 * 1000);
}
更新3:我现在在每次迭代中回显和刷新一些文本,但仍然没有效果:
while(true){
echo '0';
ob_flush();
flush(); // necessary for proper checking
if(connection_aborted()){
file_put_contents('infinity.txt', 'CONNECTION ABORTED.', FILE_APPEND);
die();
}
file_put_contents('infinity.txt', ++$i.PHP_EOL, FILE_APPEND);
usleep(250 * 1000);
}
更新4:上一次更新中显示的代码在重新启动Apache时出于一些奇怪的原因开始工作,而我没有更改php.ini中的任何设置。最终帮助的是在一开始就添加了一个ignore_user_abort(true);
。
发布于 2014-03-25 06:18:46
这样做(我在评论中留下了解释):
ignore_user_abort(1); //we'll handle it by ourselves
header('Transfer-Encoding:chunked'); //HTTP 1.1: do not capture immediately (bin)
flush();
ob_flush();
$i = 0;
set_time_limit(0);
while(1)
{
echo "0"; //do this: sending data to dead TCP connection will fail
flush();
ob_flush();
if(connection_status()!=0)
{
file_put_contents('infinity.txt', 'CONNECTION ABORTED.', FILE_APPEND);
echo "0\r\n\r\n"; //stream termination packet (double \r\n according to proto)
flush();
ob_flush();
exit();
}
file_put_contents('infinity.txt', ++$i.PHP_EOL, FILE_APPEND);
usleep(250 * 1000);
}
发布于 2014-03-25 06:01:36
请参阅您链接的同一个connection_aborted()页面上的connection_aborted。
像PHP这样的web服务器的默认过程是创建整个HTML页面,完成后将其发送到浏览器。在浏览器向服务器请求文件后,在发送该文件之前将不再进行通信。
但是,您可以使用冲洗()和相关的输出控制函数来更改此行为。这将导致PHP生成一定数量的HTML,然后将其发送到浏览器。此通信在处理过程中允许您先前尝试的connection_aborted()
工作。
编辑到添加:很高兴你得到它的工作!我还为其他寻找以下内容的人创建了一些工作测试代码:
<?php
@apache_setenv('no-gzip', 1);
@ini_set('zlib.output_compression', 0);
@ini_set('implicit_flush', 1);
for ($i = 0; $i < ob_get_level(); $i++) { ob_end_flush(); }
ob_implicit_flush(1);
ignore_user_abort(true);
ob_start();
for ($i=1;$i<10;$i++) {
sleep(2);
echo "done pass ". $i . ".<br />";
echo str_pad('',4096)."\n";
ob_flush();
if(connection_aborted()){
file_put_contents('test.txt', "CONNECTION ABORTED on pass $i.".PHP_EOL, FILE_APPEND);
exit();
}
else {
file_put_contents('test.txt', "successful pass on pass $i.".PHP_EOL, FILE_APPEND);
}
}
https://stackoverflow.com/questions/22636515
复制相似问题