finally
Das Schlüsselwort "finally" in PHP garantiert die Ausführung von Bereinigungscode nach try und catch – unabhängig von Ausnahmen.
Das PHP-Schlüsselwort „finally": Ein umfassender Leitfaden
Das Schlüsselwort finally ist Teil der Ausnahmebehandlungssyntax von PHP. Ein finally-Block wird an eine try-Anweisung angehängt und ist garantiert ausgeführt nach dem try-Block (und jedem passenden catch-Block) – unabhängig davon, ob der Code erfolgreich war, eine Exception ausgelöst hat oder vorzeitig zurückgekehrt ist. Diese Garantie macht ihn zum richtigen Ort für Bereinigungsarbeiten: Dateien schließen, Sperren freigeben, Datenbanktransaktionen beenden oder protokollieren.
Diese Seite behandelt die Syntax, die genaue Reihenfolge der Blockausführung, das Zusammenspiel von finally mit return sowie die häufigen Muster, bei denen es wirklich benötigt wird.
Syntax
Der finally-Block wird an eine try-Anweisung angehängt und wird nach den try- und catch-Blöcken ausgeführt, unabhängig davon, ob eine Ausnahme ausgelöst oder behandelt wurde. Hier ist die grundlegende Syntax für die Verwendung des Schlüsselworts finally in PHP:
Die PHP-Syntax von finally
try {
// code to be executed
} catch (Exception $e) {
// code to handle the exception
} finally {
// code to be executed regardless of whether an exception was thrown or caught
}Der catch-Block ist optional, wenn ein finally-Block vorhanden ist — try ... finally (ohne catch) ist gültiges PHP. In diesem Fall wird der finally-Block trotzdem ausgeführt, aber eine eventuell ausgelöste Ausnahme bleibt unbehandelt und wird nach Abschluss von finally nach oben weitergeleitet.
Wie die Blöcke ausgeführt werden
Die Reihenfolge ist immer dieselbe:
- Der
try-Block wird ausgeführt. - Wenn eine Ausnahme ausgelöst wird, wird der erste passende
catch-Block ausgeführt. Wenn keiner passt, wird die Ausnahme zurückgehalten, um erneut ausgelöst zu werden. - Der
finally-Block wird ausgeführt — immer. - Die Kontrolle verlässt die Anweisung (gibt einen Wert zurück oder löst eine nicht abgefangene Ausnahme erneut aus).
Dieses kleine Skript macht die Reihenfolge sichtbar:
<?php
function demo(bool $fail): void
{
try {
echo "1. try\n";
if ($fail) {
throw new Exception("boom");
}
} catch (Exception $e) {
echo "2. catch: {$e->getMessage()}\n";
} finally {
echo "3. finally\n";
}
echo "4. after\n";
}
demo(false);
echo "---\n";
demo(true);
// Output:
// 1. try
// 3. finally
// 4. after
// ---
// 1. try
// 2. catch: boom
// 3. finally
// 4. afterBeachten Sie, dass finally in beiden Fällen ausgeführt wird — einmal ohne Ausnahme, einmal nach dem catch.
Beispiele
Schauen wir uns einige praktische Beispiele an, wie das Schlüsselwort finally verwendet werden kann:
Beispiele für PHP finally
<?php
// Example 1
function divide($a, $b)
{
try {
if ($b == 0) {
throw new Exception("Division by zero.");
}
return $a / $b;
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
} finally {
echo "This code will always be executed.";
}
}
divide(10, 0);
// Output: Error: Division by zero.This code will always be executed.
// Example 2
$file = "example.txt";
$handle = fopen($file, "r");
try {
if (!$handle) {
throw new Exception("Unable to open file.");
}
// code to be executed
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
} finally {
if ($handle !== false) {
fclose($handle);
}
}
// Output: Error: Unable to open file.In diesen Beispielen verwenden wir das Schlüsselwort finally, um sicherzustellen, dass Bereinigungsoder Protokollierungscode konsistent ausgeführt wird.
finally und return
Ein finally-Block wird auch dann ausgeführt, wenn try oder catch ein return enthält. PHP wertet den Rückgabewert aus, führt dann finally aus und kehrt erst danach zurück. Wenn der finally-Block selbst einen Wert zurückgibt, überschreibt dieser Wert den früheren — eine subtile Fehlerquelle; daher sollte man es vermeiden, aus finally zurückzukehren.
<?php
function withReturn(): string
{
try {
return "from try";
} finally {
echo "finally still runs\n";
}
}
function overriding(): string
{
try {
return "from try";
} finally {
return "from finally"; // overrides the try return
}
}
echo withReturn() . "\n";
echo overriding() . "\n";
// Output:
// finally still runs
// from try
// from finallyDieselbe Überschreibungsregel gilt für Ausnahmen: Wenn finally eine Ausnahme auslöst, ersetzt diese Ausnahme jede Ausnahme oder jeden Rückgabewert, der von try/catch ausstand.
Vorteile
Die Verwendung des Schlüsselworts finally hat mehrere Vorteile:
- Verbesserte Fehlerbehandlung: Stellt sicher, dass wesentlicher Bereinigungs- oder Protokollierungscode konsistent ausgeführt wird, auch wenn Ausnahmen auftreten oder behandelt werden.
- Vereinfachter Code: Beseitigt die Notwendigkeit, die Logik zum Schließen von Ressourcen über mehrere
catch-Blöcke oder Fehlerpfade hinweg zu duplizieren.
Fazit
Zusammenfassend lässt sich sagen, dass das Schlüsselwort finally eine zuverlässige Möglichkeit bietet, wesentlichen Bereinigungscode während der Ausnahmebehandlung auszuführen — Ressourcen schließen, Sperren freigeben und protokollieren — unabhängig davon, ob eine Ausnahme ausgelöst wurde. Verwenden Sie es immer dann, wenn eine in try geöffnete Ressource unbedingt freigegeben werden muss, und vermeiden Sie return in einem finally-Block, um nicht versehentlich ein Ergebnis oder eine Ausnahme zu verschlucken.
Für einen tieferen Einblick in die PHP-Fehlerbehandlung, siehe try, catch, die Klasse Exception und den umfassenderen Leitfaden zu PHP-Ausnahmen.