Signatur
Beschreibung
register_shutdown_function() erlaubt es, eine oder mehrere Funktionen zu registrieren, die am Ende der Skriptausführung automatisch aufgerufen werden – unabhängig davon, ob das Skript normal endet, durch exit() beendet wird oder ein fataler Fehler aufgetreten ist. Typische Anwendungsfälle sind das Schließen von Datenbankverbindungen, das Schreiben von Log-Einträgen, das Bereinigen temporärer Dateien oder das Senden von abschließenden HTTP-Antworten.
Es können mehrere Shutdown-Funktionen registriert werden; sie werden in der Reihenfolge ihrer Registrierung ausgeführt (FIFO). Zusätzliche Argumente lassen sich direkt bei der Registrierung übergeben und werden beim Aufruf an den Callback weitergereicht. Die Funktion kann auch als Methode eines Objekts oder als anonyme Funktion (Closure) übergeben werden.
Innerhalb einer Shutdown-Funktion kann erneut register_shutdown_function() aufgerufen werden, um weitere Callbacks zu registrieren. Wichtig zu beachten: Der aktuelle Arbeitsverzeichniskontext kann sich in der Shutdown-Phase unter bestimmten Webservern (z. B. Apache) ändern, weshalb bei Dateizugriffen absolute Pfade bevorzugt werden sollten.
Shutdown-Funktionen eignen sich besonders gut in Verbindung mit objektorientiertem Code, etwa um Destruktor-ähnliches Verhalten zu erzwingen, das auch bei fatalen Fehlern greift – da PHP-Destruktoren in solchen Fällen möglicherweise nicht mehr aufgerufen werden.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $callback Pflicht | callable | Die aufzurufende Funktion oder Methode. Kann ein Funktionsname als String, eine anonyme Funktion (Closure), ein Array [Objekt, 'Methode'] oder ein statisches Array ['Klasse', 'Methode'] sein. |
|
| $args | mixed | Beliebig viele optionale Argumente, die beim Aufruf des Callbacks übergeben werden. Werte werden zum Zeitpunkt der Registrierung gebunden. |
Rückgabewert
Beispiele
Einfache Shutdown-Funktion zum Logging
<?php
register_shutdown_function(function(): void {
$timestamp = date('Y-m-d H:i:s');
file_put_contents(
'/var/log/app_shutdown.log',
"[{$timestamp}] Skript beendet: " . $_SERVER['SCRIPT_FILENAME'] . PHP_EOL,
FILE_APPEND
);
});
echo "Skript läuft..." . PHP_EOL;
// Normaler Ablauf endet hier; Shutdown-Funktion wird danach aufgerufen
Shutdown-Funktion als Objekt-Methode mit Fehlerbehandlung
<?php
class DatabaseManager
{
private ?PDO $pdo;
public function __construct(string $dsn)
{
$this->pdo = new PDO($dsn);
// Shutdown-Handler registrieren, auch bei fatalen Fehlern aktiv
register_shutdown_function([$this, 'shutdown']);
}
public function shutdown(): void
{
$error = error_get_last();
if ($error !== null && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR], true)) {
error_log('Fataler Fehler beim Datenbankbetrieb: ' . $error['message']);
}
$this->pdo = null; // Verbindung schließen
echo 'Datenbankverbindung sauber beendet.' . PHP_EOL;
}
public function query(string $sql): array
{
return $this->pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC);
}
}
$db = new DatabaseManager('sqlite::memory:');
echo "Datenbankmanager bereit." . PHP_EOL;
// Am Skriptende wird DatabaseManager::shutdown() automatisch aufgerufen
Mehrere Shutdown-Funktionen mit Argumentübergabe
<?php
function bereinige_temp_datei(string $pfad): void
{
if (file_exists($pfad)) {
unlink($pfad);
echo "Temporäre Datei gelöscht: {$pfad}" . PHP_EOL;
}
}
$tempDatei1 = sys_get_temp_dir() . '/upload_' . uniqid() . '.tmp';
$tempDatei2 = sys_get_temp_dir() . '/cache_' . uniqid() . '.tmp';
file_put_contents($tempDatei1, 'Temporäre Daten 1');
file_put_contents($tempDatei2, 'Temporäre Daten 2');
register_shutdown_function('bereinige_temp_datei', $tempDatei1);
register_shutdown_function('bereinige_temp_datei', $tempDatei2);
echo "Verarbeitung läuft..." . PHP_EOL;
// Beide Dateien werden am Ende in FIFO-Reihenfolge gelöscht
// Wichtig · Fallstricke
Wichtige Einschränkungen:
- Shutdown-Funktionen können nicht durch
exit()innerhalb einer anderen Shutdown-Funktion unterbrochen werden – alle registrierten Callbacks werden trotzdem ausgeführt. - HTTP-Header können in der Shutdown-Phase nicht mehr gesendet werden, wenn die Ausgabe bereits begonnen hat.
- Das aktuelle Arbeitsverzeichnis (
getcwd()) kann sich in der Shutdown-Phase ändern – daher immer absolute Pfade verwenden. - Bei einem
SIGKILL-Signal oder einem Absturz des Prozesses auf Systemebene werden Shutdown-Funktionen nicht aufgerufen. - In der Shutdown-Phase steht
error_get_last()zur Verfügung, um den letzten Fehler abzufragen – nützlich zur Erkennung fataler Fehler. - Objekte, die als Callbacks registriert sind, werden bis zum Ende der Shutdown-Phase im Speicher gehalten, was die Garbage Collection beeinflussen kann.