ignore_user_abort(bool $enable = true): bool
設置為 true 後,即使用戶關閉瀏覽器、點擊停止、網絡中斷,PHP 腳本仍會在後台繼續執行至完成或達到 max_execution_time。
ob_start()、ob_end_flush() 確保數據真正發送<?php
// 立即響應用戶
ignore_user_abort(true);
set_time_limit(0);
ob_start();
echo '任務已在後台啟動,請稍後查看結果。';
header('Connection: close');
header('Content-Length: ' . ob_get_length());
ob_end_flush();
ob_flush();
flush();
// 後台繼續執行
$urls = ['https://site1.com', 'https://site2.com', /* ... */];
foreach ($urls as $url) {
$content = file_get_contents($url);
file_put_contents('cache/' . md5($url) . '.html', $content);
sleep(1); // 禮貌延遲
}
?>
<?php
ignore_user_abort(true);
set_time_limit(0);
$interval = 300; // 5 分鐘
$logFile = __DIR__ . '/time_task.log';
while (true) {
$fp = fopen($logFile, 'a');
fwrite($fp, date('Y-m-d H:i:s') . " - 執行任務\n");
fclose($fp);
// 此處放入實際業務邏輯
// doBusinessLogic();
sleep($interval);
}
?>
警告:此為「偽定時任務」,進程常駐佔用內存,長期運行易洩漏,僅適用於無系統級排程權限的臨時方案。
<?php
// 僅適用於 PHP-FPM (Nginx/Apache mod_fcgid)
ignore_user_abort(true);
set_time_limit(0);
// 1. 立即返回響應
echo json_encode(['status' => 'accepted', 'task_id' => uniqid()]);
fastcgi_finish_request(); // 關鍵:釋放連接,瀏覽器收到響應
// 2. 後台繼續執行(此時用戶已看到結果)
sleep(10); // 模擬耗時操作
file_put_contents(__DIR__ . '/async.log', date('H:i:s') . " 背景任務完成\n", FILE_APPEND);
?>
| 局限 | 說明 | 生產級替代 |
|---|---|---|
| 需 HTTP 觸發 | 無法自主定時,依賴外部請求 | Linux crontab / systemd timer / Windows 任務計劃 |
| 進程阻塞 | 佔用 FPM worker,並發受限 | 消息隊列 + Worker 進程 |
| 無狀態持久化 | 進程異常退出任務中斷無感知 | Redis/RabbitMQ + 狀態機 + 重試機制 |
| 內存洩漏風險 | 長運行腳本累積未釋放變量 | 短命 Worker 進程 + 定期重啟 |
ignore_user_abort(true); set_time_limit(0);fastcgi_finish_request() 實現真異步響應memory_limit 保護,防止撐爆 FPMsymfony/process、laravel/queue 等成熟組件ignore_user_abort 是 PHP 實現「斷開即繼續」的基石,配合 fastcgi_finish_request 可構建輕量級異步處理。但對於高可用、高併發的生產系統,請務必升級為「消息隊列 + 獨立 Worker」架構,將 Web 層與任務層徹底解耦。