PHP 默認運行在 Web 請求上下文中:用戶關閉瀏覽器/點擊停止 → 連接中斷 → 腳本被終止。ignore_user_abort(true) 允許腳本無視客戶端斷開繼續執行,配合 set_time_limit(0) 移除執行時間限制,可實現後台長任務、簡易定時任務。
<?php
// 1. 忽略用戶斷開
ignore_user_abort(true);
// 2. 移除執行時間限制(0 = 無限制)
set_time_limit(0);
// 3. 可選:輸出緩衝控制,避免輸出導致腳本過早結束
// ob_end_clean(); // 清除並關閉輸出緩衝
// ob_start(); // 重新開啟(如需記錄日誌)
// 4. 核心循環
$interval = 30; // 秒
do {
$fp = fopen('time_task.txt', 'a+');
$str = date("Y-m-d H:i:s") . "\n";
fwrite($fp, $str);
fclose($fp);
sleep($interval); // 休眠指定秒數
} while (true);
?>
$setting = true:忽略斷開,腳本繼續運行$setting = false:斷開即終止(默認行為)| 常量 | 值 | 含義 | |
|---|---|---|---|
CONNECTION_NORMAL | 0 | 正常連接 | |
CONNECTION_ABORTED | 1 | 客戶端主動斷開(關頁/停止) | |
CONNECTION_TIMEOUT | 2 | 執行超時(超過 max_execution_time) |
| 方案 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| ignore_user_abort + sleep 循環 | 零依賴、代碼簡單、無需額外服務 | 無法精確定時、進程掛掉無自動重啟、佔用 Web Worker | 極簡項目、臨時腳本、開發測試 |
| Cron + PHP CLI | 系統級調度、精確到分、日誌標準化 | 最小粒度 1 分鐘、長任務重疊需自行加鎖 | 定時備份、報表生成、緩存預熱 |
| Systemd Timer | 秒級精度、依賴管理、自動重啟、日誌集中 | 需 root 權限配置、學習成本稍高 | 生產環境標準化部署 |
| Supervisor + Worker 進程 | 常駐進程、自動重啟、多進程並發、優雅重啟 | 需編寫 Worker 邏輯、配置管理 | 隊列消費、長連接服務、高併發任務 |
| Swoole/RoadRunner Timer | 毫秒級、協程非阻塞、內存常駐、高性能 | 框架綁定、學習曲線陡峭 | 高性能微服務、實時推送、遊戲服 |
sleep(30) 只保證「至少 30 秒」,實際受調度器影響可能更長。精確定時請用 Cron/Systemd。echo,需 ob_end_flush() 定期刷新,否則緩衝區滿/連接斷開可能阻塞。fwrite 追寫無旋轉,長期運行導致磁盤爆滿。需接入 logrotate 或自帶大小切割邏輯。ignore_user_abort 是 PHP 實現「斷開繼續執行」的核心開關,配合 set_time_limit(0)、文件鎖、信號處理、關閉函數可構建健壯的後台任務。但生產環境強烈建議遷移至 Systemd Timer / Supervisor / Swoole 等專業進程管理方案,將 PHP 腳本作為 CLI 命令被調度,而非常駐 Web Worker。