PCNTL Signals in CLI PHP
TL;DR
The PCNTL extension lets CLI PHP scripts handle OS signals (SIGTERM, SIGINT, SIGUSR1) — enabling graceful shutdown and hot reload in long-running daemons.
Explanation
pcntl_signal(SIGTERM, $handler) registers a callback for OS signals. Signals are checked at tick points (declare(ticks=1)) or via pcntl_signal_dispatch() in loops. Key signals: SIGTERM (graceful shutdown request), SIGINT (Ctrl+C), SIGUSR1/USR2 (custom), SIGHUP (reload config). Pattern for queue workers: set a flag on SIGTERM, check flag in loop, finish current task then exit cleanly. PHP-FPM manages its own signals separately. The pcntl extension is CLI-only — not available in FPM/web context. PHP 8.1: async signals via pcntl_async_signals(true) removes need for ticks.
Common Misconception
✗ PHP CLI scripts terminate immediately on SIGTERM — by default yes, but with pcntl_signal() you can intercept and handle gracefully.
Why It Matters
Graceful shutdown on SIGTERM prevents data corruption in queue workers and daemons — the job in progress completes before the process exits.
Common Mistakes
- Not calling pcntl_signal_dispatch() in tight loops — signals accumulate but handler never fires.
- Using ticks=1 on every statement — performance overhead. Use pcntl_async_signals(true) instead.
- Handling SIGKILL — impossible to catch, always terminates immediately.
Code Examples
✗ Vulnerable
// Worker that can't shut down gracefully:
while (true) {
$job = $queue->pop();
processJob($job); // Killed mid-job on deploy
}
✓ Fixed
pcntl_async_signals(true); // PHP 8.1+ — no ticks needed
$running = true;
pcntl_signal(SIGTERM, function() use (&$running) {
$running = false;
});
pcntl_signal(SIGINT, function() use (&$running) {
$running = false;
});
while ($running) {
$job = $queue->pop();
if ($job) processJob($job); // Completes current job before exit
else usleep(100000);
}
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
23 Mar 2026
Views
32
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 1
No pings yesterday
Perplexity 8
Amazonbot 7
Unknown AI 4
Google 4
ChatGPT 3
SEMrush 2
Ahrefs 1
Also referenced
How they use it
crawler 25
crawler_json 1
pre-tracking 3
Related categories
⚡
DEV INTEL
Tools & Severity
🟡 Medium
⚙ Fix effort: Medium
⚡ Quick Fix
Use pcntl_async_signals(true) (PHP 8.1+) instead of ticks. Set a $running flag on SIGTERM/SIGINT. Check flag in worker loop to exit cleanly after current task.
📦 Applies To
PHP 7.1+
cli
queue-worker
🔗 Prerequisites
🔍 Detection Hints
pcntl_signal|SIGTERM
Auto-detectable:
✗ No
phpstan
⚠ Related Problems
🤖 AI Agent
Confidence: Low
False Positives: High
✗ Manual fix
Fix: Medium
Context: File