Gibt es eine Möglichkeit, eine Ausnahme abzufangen, ohne eine Variable erstellen zu müssen?
Lesezeit: 1 Minute
Matthias Napoli
In PHP fange ich manchmal einige Ausnahmen mit try/catch ab:
try {
...
} catch (Exception $e) {
// Nothing, this is normal
}
Mit dieser Art von Code lande ich bei der Variablen $e das für nichts erstellt wird (viele Ressourcen), und PHP_MD (PHP Mess Detector) erstellt eine Warnung wegen einer nicht verwendeten Variable.
Eine Ausnahme sollte nicht als “normal” behandelt werden – entweder ist es eine Ausnahme oder nicht. Was löst die Ausnahmen aus?
– JohnParker
27. Januar 2011 um 18:21 Uhr
Ich teste, ob das Modell eine Ausnahme auslöst, wenn es sollte. Ich habe also einen leeren Catch-Block, weil ich nur testen möchte, dass die Ausnahme ausgelöst wurde.
– Matthieu Napoli
28. Januar 2011 um 14:03 Uhr
Yivi
Ab PHP 8 ist es möglich, einen nicht erfassenden Fang zu verwenden.
try {
readFile($file);
} catch (FileDoesNotExist) {
echo "File does not exist";
} catch (UnauthorizedAccess) {
echo "User does not have the appropriate permissions to access the file";
log("User attempted to access $file");
}
Damit ist es für einige Grenzfälle, in denen die Ausnahmedetails nicht relevant sind und der Ausnahmetyp bereits den gesamten erforderlichen Kontext bereitstellt, möglich, die Ausnahme abzufangen, ohne eine neue Variable zu erstellen.
Könnten Sie eine Schulungsdokumentation darüber bereitstellen, wie dies ohne a funktioniert Throw? Ich überprüfe meine üblichen Spots, aber sie sind alle für <8.0 gemacht
– jpgerb
10. Mai um 5:32 Uhr
TarranJones
Sie können mit PHP 8 @see
PHP5,7
Nein, aber Sie können es deaktivieren.
try {
...
} catch (Exception $e) {
// Nothing, this is normal
unset($e);
}
Wenn PHPMD dieses Problem verursacht, können Sie die Warnung unterdrücken.
class Bar {
/**
* This will suppress UnusedLocalVariable
* warnings in this method
*
* @SuppressWarnings(PHPMD.UnusedLocalVariable)
*/
public function foo() {
try {
...
} catch (Exception $e) {
// Nothing, this is normal
unset($e);
}
}
}
Ich gehe davon aus, dass Sie die Ausnahme nur abfangen, weil Sie es nicht brauchen, weil Sie es wollen. Mit PHP 5.7 müssen Sie a verwenden catch wenn Sie verwenden möchten try und wenn Sie a verwenden catch du musst eine Variable deklarieren.
Das ist der springende Punkt bei Ausnahmen – Sie können mehrere verschiedene catch-Blöcke haben, um alle Ausnahmen abzufangen, die Sie behandeln möchten. Die Daten der Ausnahme müssen irgendwo zugewiesen werden, daher die Variable. Du könntest einfach so etwas tun unset($e) innerhalb des catch-Blocks, wenn Sie diese Warnungen wirklich nicht sehen möchten … oder deaktivieren Sie die Warnungen (im Allgemeinen eine schlechte Idee).
Wouter Florijn
Ich stimme den Antworten von Marc B und Artefacto grundsätzlich nicht zu. Es gibt Fälle, in denen das Weglassen des Fangs besser oder sogar die einzige Option ist. Insbesondere bei Verwendung externer Bibliotheken (bei denen Sie keine Kontrolle darüber haben, welche Ausnahmen ausgelöst werden) und/oder asynchroner Vorgänge.
Zum Beispiel:
Ich möchte eine Datei nur erstellen, wenn sie noch nicht existiert. Ich verwende eine externe E/A-Bibliothek. Stellen Sie sich vor, es hat File::exists($fileName) und File::create($fileName) Methoden.
Option 1 (wenn das Weglassen des Fangs möglich war):
try {
File::create($fileName);
}
// Go on with the rest of the code.
Variante 2 (ohne try/catch):
if (!File::exists($fileName))
File::create($fileName);
Hier ist Option 1 vollkommen gültig, da Option 2 zwei wichtige Probleme hat:
Wenn mehrere Threads gleichzeitig laufen und diesen Codeabschnitt durchlaufen, könnte es sein, dass Thread A zuerst prüft, ob die Datei existiert. Als nächstes prüft Thread B, ob die Datei existiert. Sie finden beide, dass es nicht existiert. Thread A erstellt die Datei. Thread B versucht dann, es erneut zu erstellen, und löst eine Ausnahme aus, obwohl Sie die if-Prüfung verwenden.
Es ist sehr wahrscheinlich, dass die Bibliothek selbst dies bereits durchführt !File::exists($fileName) überprüfen. Sie verschwenden also einen bereits geführten Anruf.
Beachten Sie, dass wenn File::create andere Ausnahmen auslöst, die unerwartet sein könnten, wäre es gut, diese abzufangen.
Fazit
Zu sagen, dass etwas ist noch nie eine gute Idee, ist fast nie eine gute Idee. Es gibt immer Ausnahmen (hehe) von der Regel. Wie jede Konvention oder jedes Designmuster ist es nur eine Faustregel, die weniger erfahrenen Entwicklern helfen soll, die richtige Entscheidung zu treffen.
Nein.
Auf jeden Fall ist es im Allgemeinen keine gute Idee, eine Ausnahme abzufangen und nichts zu tun; Ausnahmen existieren genau, um Sie zu zwingen, den außergewöhnlichen Umstand zu handhaben (andernfalls wird die Ausführung abgebrochen), daher ist es verständlich, dass die Sprache einen solchen Anwendungsfall nicht erleichtert.
Gleichzeitig ist es im Allgemeinen keine gute Idee, eine Ausnahme auszulösen, wenn Sie wahrscheinlich nur einen Statuscode benötigen. Wenn Ausnahmen tatsächlich Ausnahmen wären, würden wir nicht so viele nutzlose Try/Catch-Blöcke sehen. Insbesondere werfen viele Netzwerkdienstprogramme Ausnahmen, wenn es ein Netzwerkproblem gibt, was die Kapselung unterbricht und dem Programmierer nicht wirklich hilft. Ein Netzwerkproblem sollte kein Ausnahmefall sein, wenn Sie ein Netzwerkdienstprogramm sind, Sie sollten in der Lage sein, es intern zu behandeln.
– Roger Halliburton
27. Januar 2011 um 20:09 Uhr
Ab PHP 8.0 es kann ohne Variablen eingegeben werden, aber der allgemeine Fall für jeden Exception ist jetzt Throwable. Klasse Exception implementiert Throwable.
Gleichzeitig ist es im Allgemeinen keine gute Idee, eine Ausnahme auszulösen, wenn Sie wahrscheinlich nur einen Statuscode benötigen. Wenn Ausnahmen tatsächlich Ausnahmen wären, würden wir nicht so viele nutzlose Try/Catch-Blöcke sehen. Insbesondere werfen viele Netzwerkdienstprogramme Ausnahmen, wenn es ein Netzwerkproblem gibt, was die Kapselung unterbricht und dem Programmierer nicht wirklich hilft. Ein Netzwerkproblem sollte kein Ausnahmefall sein, wenn Sie ein Netzwerkdienstprogramm sind, Sie sollten in der Lage sein, es intern zu behandeln.
– Roger Halliburton
27. Januar 2011 um 20:09 Uhr
Gesunde Kürbisse
Ausnahmen werden nicht nur für außergewöhnliche Umstände verwendet.
Dieses Szenario verwendet tatsächlich Ausnahmen, um sicherzustellen, dass der Benutzer abgemeldet wird. An diesem Punkt im Skript ist es sehr ressourcenintensiv, herauszufinden, welche Daten bereinigt werden sollten, sodass es eigentlich schneller ist, einfach alles zu kürzen und die Ausnahmen abzufangen.
Eine Ausnahme sollte nicht als “normal” behandelt werden – entweder ist es eine Ausnahme oder nicht. Was löst die Ausnahmen aus?
– JohnParker
27. Januar 2011 um 18:21 Uhr
Ich teste, ob das Modell eine Ausnahme auslöst, wenn es sollte. Ich habe also einen leeren Catch-Block, weil ich nur testen möchte, dass die Ausnahme ausgelöst wurde.
– Matthieu Napoli
28. Januar 2011 um 14:03 Uhr