Signatur
Beschreibung
pcntl_signal() ermöglicht es, für einen laufenden PHP-Prozess eine Verarbeitungsroutine (Handler) für Unix/POSIX-Signale zu definieren. Trifft ein registriertes Signal ein, wird der angegebene Callback aufgerufen — entweder sofort (mit pcntl_async_signals(true)) oder beim nächsten expliziten Aufruf von pcntl_signal_dispatch().
Als $handler kann ein callable angegeben werden, das als erstes Argument die Signal-Nummer erhält und optional als zweites Argument ein Array mit weiteren Signal-Informationen (siginfo). Alternativ kann SIG_DFL (Standard-Systemverhalten wiederherstellen) oder SIG_IGN (Signal ignorieren) übergeben werden.
Typische Anwendungsfälle sind Daemon-Prozesse, die auf SIGTERM ordnungsgemäß heruntergefahren werden sollen, Worker-Prozesse, die via SIGHUP ihre Konfiguration neu laden, oder langläufige CLI-Skripte, die auf SIGINT (Ctrl+C) reagieren müssen.
Wichtig: Die PCNTL-Extension ist nur auf Unix-ähnlichen Systemen verfügbar und nicht im Web-SAPI-Kontext (Apache, FPM) gedacht — sie ist für CLI-Prozesse vorgesehen. Die Signal-Verarbeitung erfordert entweder pcntl_async_signals(true) oder regelmäßige Aufrufe von pcntl_signal_dispatch() im Prozess-Loop.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $signal Pflicht | int | Die Signal-Nummer, für die der Handler registriert werden soll. Typische Werte sind Konstanten wie SIGTERM, SIGINT, SIGHUP, SIGUSR1 etc. |
|
| $handler Pflicht | callable|int | Der zu registrierende Handler. Entweder ein callable (Funktion, Methode oder Closure) mit den Parametern (int $signo, mixed $siginfo), oder eine der Konstanten SIG_DFL (Standard-Systemverhalten) bzw. SIG_IGN (Signal ignorieren). |
|
| $restart_syscalls | bool | true | Gibt an, ob unterbrochene Systemaufrufe nach der Signal-Verarbeitung automatisch neu gestartet werden sollen (SA_RESTART). Standardmäßig true. Bei false können blockierende Funktionen (z. B. sleep()) vorzeitig abbrechen. |
Rückgabewert
true bei Erfolg zurück, false bei einem Fehler (z. B. ungültige Signal-Nummer oder nicht unterstütztes Signal).Beispiele
Graceful Shutdown bei SIGTERM in einem Daemon
<?php
// Asynchrone Signal-Verarbeitung aktivieren (PHP 7.1+)
pcntl_async_signals(true);
$running = true;
// Handler für SIGTERM und SIGINT registrieren
pcntl_signal(SIGTERM, function (int $signo) use (&$running): void {
echo "Signal {$signo} empfangen – fahre sauber herunter...\n";
$running = false;
});
pcntl_signal(SIGINT, function (int $signo) use (&$running): void {
echo "Ctrl+C erkannt – beende Prozess.\n";
$running = false;
});
echo "Daemon gestartet (PID: " . getmypid() . ")\n";
while ($running) {
// Simulierte Arbeit
echo "Arbeite...\n";
sleep(1);
}
echo "Prozess beendet.\n";
Konfiguration neu laden bei SIGHUP
<?php
pcntl_async_signals(true);
$config = ['debug' => false, 'workers' => 4];
pcntl_signal(SIGHUP, function () use (&$config): void {
echo "SIGHUP empfangen – lade Konfiguration neu.\n";
// Konfigurationsdatei neu einlesen (hier vereinfacht)
$config['debug'] = true;
$config['workers'] = 8;
echo "Neue Konfiguration: " . json_encode($config) . "\n";
});
// Signal ignorieren mit SIG_IGN
pcntl_signal(SIGUSR2, SIG_IGN);
// Standard-Handler wiederherstellen
pcntl_signal(SIGUSR1, SIG_DFL);
echo "PID: " . getmypid() . " – sende SIGHUP zum Testen: kill -HUP " . getmypid() . "\n";
for ($i = 0; $i < 10; $i++) {
sleep(1);
}
Manuelles Dispatching ohne async signals
<?php
// Ohne pcntl_async_signals: manueller Dispatch im Loop
$stop = false;
pcntl_signal(SIGTERM, function () use (&$stop): void {
$stop = true;
});
while (!$stop) {
// Signale im Loop manuell verarbeiten
pcntl_signal_dispatch();
echo "Tick\n";
usleep(500000); // 0,5 Sekunden
}
// Wichtig · Fallstricke
Verfügbarkeit: pcntl_signal() ist nur verfügbar, wenn PHP mit der PCNTL-Extension kompiliert wurde (--enable-pcntl). Auf Windows-Systemen steht die Funktion nicht zur Verfügung.
Signal-Verarbeitung aktivieren: Seit PHP 7.1 empfiehlt sich pcntl_async_signals(true) am Anfang des Skripts, um Signale asynchron zu verarbeiten. Alternativ muss pcntl_signal_dispatch() regelmäßig im Hauptloop aufgerufen werden, da PHP Signale sonst erst zwischen Opcode-Ausführungen prüft.
Nicht im Web-SAPI verwenden: Der Einsatz in Web-Server-Umgebungen (Apache mod_php, PHP-FPM) kann zu unvorhersehbarem Verhalten führen und ist nicht unterstützt. pcntl_signal() ist ausschließlich für CLI-Prozesse und Daemons gedacht.
Unkündbare Signale: Die Signale SIGKILL und SIGSTOP können nicht abgefangen oder ignoriert werden — Versuche werden stillschweigend fehlschlagen oder einen Fehler zurückgeben.