dongpu3792 2014-03-25 13:46
浏览 146
已采纳

PHP在用户断开连接时中止无限循环

I am doing a minor experiment with PHP. I have a file named 'infinity.txt', and in that file, I write an incrementing number every 0.25 seconds.

while(true){

    file_put_contents('infinity.txt', ++$i.PHP_EOL, FILE_APPEND);
    usleep(250 * 1000);

}

This works fine and well, but when I close the tab in my browser, the script continues running. A browser request abort is no Ctrl. + C, so there's no surprise in that, but I was still wondering whether it is possible to abort an infinite loop when the user disconnects, or if there is any method to see if the user is still connected.

Calling register_shutdown_function beforehand is completely useless, by the way, even when the linked function has a die() within.

UPDATE: It seems to me that something might be done using the connection_aborted() function.

UPDATE 2: I have changed my code to look like this, but alas, the infinite loop does not cancel:

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);

}

UPDATE 3: I am now echoing and flushing some text in every iteration, yet still to no avail:

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);

}

UPDATE 4: The code shown in the previous update started working for some weird reason upon restarting Apache, without me changing any settings in the php.ini. What ultimately helped was adding an ignore_user_abort(true); at the very beginning.

  • 写回答

2条回答 默认 最新

  • drc4925 2014-03-25 14:18
    关注

    Do this way (I left explanation in comments):

    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
    
    "; //stream termination packet (double 
     according to proto)
            flush();
            ob_flush();
            exit();
    
        }
    
        file_put_contents('infinity.txt', ++$i.PHP_EOL, FILE_APPEND);
        usleep(250 * 1000);
    
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 关于smbclient 库的使用
  • ¥15 微信小程序协议怎么写
  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画