首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP ignore_user_abort:瀏覽器關閉後繼續執行長任務(異步處理、導出、視頻轉碼)

     編輯:PHP 綜合知識

核心函數

ignore_user_abort(bool $enable = true): int

設置客戶端斷開連接(關閉瀏覽器、網絡中斷)時,腳本是否繼續執行。返回值為舊設置(0/1)。

完整 Demo:後台寫入日誌 100 次,每次間隔 2 秒

<?php
ignore_user_abort(true);   // 關鍵:啟用斷開繼續執行
set_time_limit(0);         // 移除最大執行時間限制 (需 php.ini 允許)

$file = '/tmp/ignore_user.txt';
if (!file_exists($file)) file_put_contents($file, '');

$fp = fopen($file, 'ab'); // 追加二進制模式
if (!$fp) exit("無法打開文件: $file");

for ($i = 0; $i < 100; $i++) {
    $time = date('Y-m-d H:i:s');
    echo "$time\n"; // 如未斷開連接,可見輸出
    if (fwrite($fp, "$time\n") === false) {
        fclose($fp);
        exit("寫入失敗: $file");
    }
    echo "寫入完成: $time\n";
    sleep(2);
}
fclose($fp);
echo "任務結束\n";

典型應用場景

場景說明
大數據導出 (Excel/CSV/PDF)用戶點擊導出,頁面提示「正在後台生成,稍後下載」,腳本持續寫文件
視頻/音頻轉碼上傳後啟動 ffmpeg 長時間轉碼,不因用戶關頁中斷
批量郵件/推送發送循環發送數萬條,耗時數分鐘
定時任務觸發器Web 請求觸發長時間運行的維護腳本
數據同步/ETL跨系統大量數據同步

生產級增強要點

  1. 進程守護:使用 Supervisor / Systemd 管理長運行腳本,而非依賴 Web 請求觸發。
  2. 任務隊列:Redis/RabbitMQ + Worker (PHP CLI) 異步消費,Web 端秒級響應。
  3. 狀態持久化:資料庫記錄任務 ID、進度、狀態、結果路徑,前端輪詢/WS 獲取進度。
  4. 鎖機制:防止重複啟動同一任務 (Redis SETNX / 文件鎖)。
  5. 日誌輪轉:logrotate 管理輸出日志,防止磁盤爆滿。
  6. 內存管理:長循環中定期 gc_collect_cycles()、釋放大變量 unset()。
  7. 信號處理:捕獲 SIGTERM 優雅退出 (保存進度、釋放鎖)。

對比:ignore_user_abort vs 隊列 Worker

維度ignore_user_abort (Web 觸發)隊列 Worker (CLI)
可靠性低 (Web 服務器重啟/超時會殺死)高 (進程管理器守護、自動重啟)
併發控制難 (受 PHP-FPM 進程數限制)靈活 (Worker 數獨立配置)
監控運維困難 (混雜在 Web 日志中)清晰 (獨立日志、指標、告警)
部署複雜度低 (無新增組件)中 (需隊列、Worker、監控)
推薦場景極簡內部工具、臨時腳本、低頻任務所有生產級異步任務

最佳實踐建議

新項目直接上隊列 (Laravel Queue, Symfony Messenger, Hyperf, 自研)。
僅在**極簡環境、無法引入隊列組件、任務極低頻**時使用 ignore_user_abort 作為戰術補丁。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved