php-fpm提前结束一个响应,但继续执行代码

函数 ignore_user_abort 在PHP官方手册里说明是

设置客户端断开连接时是否中断脚本的执行
PHP 以命令行脚本执行时,当脚本终端结束,脚本不会被立即中止
除非设置 value 为 TRUE,否则脚本输出任意字符时会被中止

大白话就是,设置了这个值,你离开了我也照样活着照样过
不设置就是你离开我我就和你同归于尽。

与这个函数相关的还有两个函数

  1. connection_aborted() – 检查客户端是否已经断开
  2. connection_status() – 返回连接的状态位
在connection_aborted中有个比较有趣的?(栗子)
<?php
ignore_user_abort(true);
header('Transfer-Encoding:chunked');
ob_flush();
flush();
$start = microtime(true);
$i = 0;
// Use this function to echo anything to the browser.
function vPrint($data){
    if(strlen($data))
        echo dechex(strlen($data)), "\r\n", $data, "\r\n";
    ob_flush();
    flush();
}
// You MUST execute this function after you are done streaming information to the browser.
function endPacket(){
    echo "0\r\n\r\n";
    ob_flush();
    flush();
}

do{
    echo "0";
    ob_flush();
    flush();
    if(connection_aborted()){
        // This happens when connection is closed
        file_put_contents('/tmp/test.tmp', sprintf("Conn Closed\nTime spent with connection open: %01.5f sec\nLoop itterations: %s\n\n", microtime(true) - $start, $i), FILE_APPEND);
        endPacket();
        exit;
    }
    usleep(50000);
    vPrint("I get echo'ed every itteration (every .5 second)<br />\n");
}while($i++ < 200);
endPacket();

大概就是 执行后 将不断的向浏览器输出 I get….
直到 $i 大于200之后执行endPacket结束
其中在结束前如果客户端断开
也就是connection_aborted返回1的时候将执行test.tmp 写入
最后endPacket结束

延展一下:

定时全站推送。
1.后台设置推送内容
2.定时检测变化
3.有变化推送 -> 写入日志
4.无变化继续等待。

(例子中检测变化就用文件代替好了)

<?php
/**
 * ███████╗███████╗
 * ██╔════╝╚══███╔╝
 * █████╗    ███╔╝
 * ██╔══╝   ███╔╝
 * ███████╗███████╗
 * ╚══════╝╚══════╝
 * Created by PhpStorm.
 * User: EZ
 * Date: 2018/12/8
 * Time: 20:57
 */

// 改动content.txt 内容就会自动在send.log中更新

ignore_user_abort(true);
header('Transfer-Encoding:chunked');

// 获取发送内容文件MD5
$md5 = md5_file('DB/content.txt');

// 记录内容文件的MD5
file_put_contents('DB/switch.txt', $md5);

do {
    // 设定一秒检测一次
    sleep(1);

    // 10用户
    $user    = 10;

    // 获取内容文件的MD5
    $md5     = file_get_contents('DB/switch.txt');

    // 获取最新发送内容文件MD5
    $newMd5  = md5_file('DB/content.txt');

    // 获取最新发送内容
    $content = file_get_contents('DB/content.txt');

    // 比对,不一致说明内容更新
    if ($md5 != $newMd5) {

        // 循环所有用户
        while($user-- > 0) {
            /**
             * 执行发送内容巴拉巴拉小魔仙
             */

            // 记录发送日志
            file_put_contents('DB/send.log', sprintf("这是{$user}号用户,内容\"{$content}\"发送成功!<br />\n"), FILE_APPEND);

        }

        // 记录最新发送内容文件MD5
        file_put_contents('DB/switch.txt', $newMd5);
        continue;

    } else {
        continue;
    }


} while (true);



发表评论

邮箱地址不会被公开。 必填项已用*标注