使用ignore_user_abort(true)实现客户端断开连接后继续脚本执行

<?php
declare(strict_types=1);
ini_set('display_errors', 'On');
error_reporting(-1);

// https://www.domain.com/task.php?action=start // 启动任务地址
// https://www.domain.com/task.php?action=stop  // 停止任务地址

const TASK_STOP_KEY = 'TASK_STOP_KEY';

$redis = new Redis();
$redis->connect('localhost');
$redis->auth('************');

$action = (string)($_GET['action'] ?? '');

//========== 启动任务 ==========//
if ($action === 'start') {
    ignore_user_abort(true); // 客户端断开连接时不中断脚本的执行
    set_time_limit(0); // 不限制脚本最大执行时间

    $counter = 999;

    while (true) {
        // 检查是否发出停止任务信号
        $stop = $redis->get(TASK_STOP_KEY);
        if ($stop === TASK_STOP_KEY) {
            $redis->del(TASK_STOP_KEY);
            break;
        }

        file_put_contents(__DIR__ . "/task.$counter.txt", '');

        $counter--;

        if ($counter === 0) {
            break;
        }

        sleep(1);
    }

    // 看到“task.completed.txt”文件则说明任务已完成(或停止)
    file_put_contents(__DIR__ . '/task.completed.txt', '');
    exit('任务执行完毕');
}

//========== 停止任务 ==========//
if ($action === 'stop') {
    $ok = $redis->set(TASK_STOP_KEY, TASK_STOP_KEY);
    if ($ok) {
        exit('停止任务成功');
    }
    exit('停止任务失败');
}

exit('error');

Copyright © 2024 码农人生. All Rights Reserved