Gibt es eine Möglichkeit, eine Ausnahme abzufangen, ohne eine Variable erstellen zu müssen?

Lesezeit: 1 Minute

Benutzer-Avatar
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

Benutzer-Avatar
Yivi

Ab PHP 8 ist es möglich, einen nicht erfassenden Fang zu verwenden.

Dies ist der relevante RFCdie mit 48 zu 1 positiv gestimmt wurde.

Jetzt wird es möglich sein, so etwas zu tun:

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

Benutzer-Avatar
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.

PHPMD-Unterdrückungswarnungen

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

Benutzer-Avatar
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:

  1. 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.
  2. 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.

try {
    ...
} catch (CustomException) {
    // CustomException
} catch (Throwable) {
    //All other classes implementing Throwable interface
}

  • 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


Benutzer-Avatar
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.

        try {
        GDS::$DB->exec('DELETE FROM sessions WHERE session_id = ' . session_id());
        GDS::$DB->exec('DELETE FROM sessions WHERE user_id = ' . $this->data['user_id']);
    } catch(PDOException $ex) {}
    session_regenerate_id(true);
    setcookie('bis_[user_id]', 0, time() - 1, null, null, false, true);
    setcookie('bis_[session_start]', 0, time() - 1, null, null, false, true);
    setcookie('bis_[session_time]', 0, time() - 1, null, null, false, true);

  • Wie ist das eine Antwort?

    – rr-

    20. September 2014 um 16:21 Uhr

  • Außerdem wird die zweite Anweisung übersprungen, wenn die erste wirft, was wahrscheinlich nicht beabsichtigt war.

    – Artefakt

    28. Dezember 2017 um 23:51 Uhr

1303480cookie-checkGibt es eine Möglichkeit, eine Ausnahme abzufangen, ohne eine Variable erstellen zu müssen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy