守護進程是在背景長期執行、不受終端機控制的進程。PHP 透過 pcntl_fork() 與 posix_setsid() 可建立標準的 Unix 守護進程,適用於常駐服務、佇列消費者、定時排程等場景。
posix_setsid() 建立新會話,成為會話領導者,失去控制終端機。<?php
$pid = pcntl_fork();
if ($pid < 0) {
exit(1); // Fork 失敗
} elseif ($pid > 0) {
exit(0); // 父進程退出
}
// 子進程繼續
$sid = posix_setsid();
if ($sid < 0) {
exit(1); // 建立會話失敗
}
// 可選:切換工作目錄至根目錄,避免掛載點被佔用
chdir('/');
// 可選:關閉標準輸入/輸出/錯誤
fclose(STDIN);
fclose(STDOUT);
fclose(STDERR);
// 守護進程主迴圈
for ($i = 0; $i <= 60; $i++) {
// 執行背景任務:檢查佇列、寫入日誌、監控服務等
error_log("Daemon 執行中... 週期 $i");
sleep(5);
}
?>
// 第一次 fork 後,子進程再 fork 一次
$pid2 = pcntl_fork();
if ($pid2 > 0) exit(0); // 第一代子進程退出
// 第二代子進程繼續執行 posix_setsid() 及主邏輯
nohup php daemon.php >/dev/null 2>&1 & 或系統服務管理器(systemd、supervisord)管理啟動/重啟/日誌。gc_collect_cycles()。pcntl_signal(SIGTERM, ...) 實現優雅關機。掌握守護進程撰寫,是 PHP 進入系統級背景服務開發的關鍵門檻。