Start · Sprachen · PHP · Referenz · pcntl_signal

pcntl_signal

Funktion

Registriert einen Signal-Handler (Callback) für ein POSIX-Signal, sodass PHP-Prozesse auf Betriebssystem-Signale wie <code>SIGTERM</code> oder <code>SIGUSR1</code> reagieren können.

seit PHP 4.1.0 Kategorie: misc

Signatur

pcntl_signal(int $signal, callable|SIG_DFL|SIG_IGN $handler, bool $restart_syscalls = true): bool

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

Typ
bool
Beschreibung
Gibt 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";
Daemon gestartet (PID: 12345) Arbeite... Arbeite... Signal 15 empfangen – fahre sauber herunter... Prozess beendet.

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);
}
PID: 12345 – sende SIGHUP zum Testen: kill -HUP 12345 SIGHUP empfangen – lade Konfiguration neu. Neue Konfiguration: {"debug":true,"workers":8}

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
}
Tick Tick Tick ...

// 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.