php: try-catch fängt nicht alle Ausnahmen ab

Lesezeit: 4 Minuten

Ich versuche Folgendes zu tun:

try {
    // just an example
    $time="wrong datatype";
    $timestamp = date("Y-m-d H:i:s", $time);
} catch (Exception $e) {
    return false;
}
// database activity here

Kurz gesagt: Ich initialisiere einige Variablen, die in die Datenbank gestellt werden sollen. Wenn die Initialisierung aus irgendeinem Grund fehlschlägt – zB weil $time nicht das erwartete Format hat – möchte ich, dass die Methode false zurückgibt und keine falschen Daten in die Datenbank eingibt.

Allerdings werden solche Fehler nicht von der ‘catch’-Anweisung abgefangen, sondern von der globalen Fehlerbehandlung. Und dann geht das Drehbuch weiter.

Gibt es eine Möglichkeit, dies zu umgehen? Ich dachte nur, es wäre sauberer, es so zu machen, anstatt jede Variable manuell zu überprüfen, was ineffektiv erscheint, wenn man bedenkt, dass in 99% aller Fälle nichts Schlimmes passiert.

  • Das liegt daran, dass Ausnahmen nicht überall in PHP implementiert sind. Sie sind eine PHP5-Ergänzung, und nur sehr wenige der eingebauten Funktionen werden sie auslösen. Stattdessen müssen Sie die Rückgabewerte der meisten Funktionen überprüfen.

    – Michael Berkowski

    17. März 2013 um 14:07 Uhr


try {
  // call a success/error/progress handler
} catch (\Throwable $e) { // For PHP 7
  // handle $e
} catch (\Exception $e) { // For PHP 5
  // handle $e
}

  • Vielen Dank für dieses Code-Snippet, das möglicherweise eine begrenzte, sofortige Hilfe bietet. EIN richtige Erklärung würde seinen langfristigen Wert erheblich verbessern, indem es aufzeigt, warum dies eine gute Lösung für das Problem ist, und es für zukünftige Leser mit anderen, ähnlichen Fragen nützlicher machen würde. Bitte bearbeiten Sie Ihre Antwort, um eine Erklärung hinzuzufügen, einschließlich der von Ihnen getroffenen Annahmen.

    – rsjaffe

    6. August 2018 um 4:00 Uhr

  • @YvetteColomb, Oh, hier ist also ein Geist, der meine Meinung aufhebt !!! 😉 Aber das glaube ich immer noch einige Fragen kann eine einzelne Wortantwort haben. Was ist die Antwort auf die Frage 4 + 4? Eine sehr kurze Antwort kann ohne Erklärung hinzugefügt werden, nur ein Wort: 2, warum müssen wir dann schreiben: “Die richtige Antwort auf die 4 + 4-Aussage, die Ihre Frage war, war 2 …!” Auch hier stimme ich den ausführlicheren Erläuterungen in den Antworten zu. Aber ich meine, nur einige von ihnen.

    – Nabi KAZ

    12. August 2018 um 13:24 Uhr

  • Diese kurze Antwort ist alles, was ich brauchte. Aber ich bin mir nicht sicher, ob 4 + 4 = 2 ist.

    – MusikTier

    16. Januar 2019 um 3:16 Uhr

  • Ja, das ist stark unterdokumentiert, man merkt es kaum, wenn man Glück hat und zu beiden kommt php.net/manual/en/class.error.php und php.net/manual/en/class.exception.php Links … weil derjenige, der dies enthalten sollte: php.net/manual/en/language.exceptions.phpenthält nicht einmal das Wort Throwable (im Dokumentteil).

    – jave.web

    18. September 2019 um 13:21 Uhr

  • Unter welchen Umständen würde dies zum späteren Catch-Block gehen? Wenn die Exception-Klasse die Throwable-Schnittstelle implementiert, würde dies nicht immer im ersten Catch-Block abgefangen werden?

    – Gemmu

    21. Juli 2021 um 9:51 Uhr


Lösung Nr. 1

Verwenden ErrorException um Fehler in Ausnahmen umzuwandeln, die behandelt werden müssen:

function exception_error_handler($errno, $errstr, $errfile, $errline ) {
    throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
}
set_error_handler("exception_error_handler");

Lösung Nr. 2

try {
    // just an example
    $time="wrong datatype";
    if (false === $timestamp = date("Y-m-d H:i:s", $time)) {
        throw new Exception('date error');
    }
} catch (Exception $e) {
    return false;
}

  • Ein paar Anmerkungen: 1) Wenn es nicht erwünscht ist, überall in der Anwendung Ausnahmen anstelle von Fehlern auszulösen, kann dies bei Bedarf aktiviert und die reguläre Fehlerbehandlung wiederhergestellt werden restore_error_handler(). 2) Ich erwarte, dass #2 immer noch eine Warnung ausgibt. Es gilt das gleiche Konzept: Die Fehlerberichtsebene könnte mit geändert werden error_reporting() und danach wieder geändert.

    – Schlaumeier

    17. März 2013 um 14:23 Uhr

  • Die Warnung MUSS sowieso geworfen werden. Es sind Informationen, die Sie irgendwo speichern müssen. Wenn Sie es nicht sehen möchten, schalten Sie es einfach aus error_display

    – Federkun

    17. März 2013 um 14:27 Uhr

  • Lösung Nr. 2 ist, wie Js es macht … es ist gut, wenn Sie wissen, was Sie tun

    – Ray Foss

    3. Februar 2018 um 19:51 Uhr

  • Folgefrage: Ist es eine gute Idee, Lösung Nr. 1 in Ihren MVC-Anwendungen zu verwenden? Ich habe das Gefühl, dass die globale Verwendung den Zweck von Ausnahmen bei wiederholter Verwendung zunichte macht restore_error_handler() fühlt sich sehr hackig an.

    Benutzer2286243

    19. März 2018 um 12:50 Uhr


  • Nur im Debug-Modus @VarunAgrawal, während der Entwicklung. Ich würde mich nicht auf eine globale PHP-Einstellung verlassen, um korrekt zu handhaben, wie Ihre Anwendung am Ende tatsächlich ausgeführt wird.

    – Federkun

    20. März 2018 um 20:50 Uhr

Je kürzer ich gefunden habe:

set_error_handler(function($errno, $errstr, $errfile, $errline ){
    throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
});

Macht alle Fehler zu einer abfangbaren Instanz ErrorException

Benutzer-Avatar
Amal Magdy

Es ist möglich zu verwenden catch(Throwable $e) um alle Ausnahmen und Fehler wie folgt abzufangen:

catch ( Throwable $e){
    $msg = $e->getMessage();
}

Es ist auch möglich, mehrere Typen für die zu definieren $e Parameter im Fang:

try {
    // just an example
    $time="wrong datatype";
    $timestamp = date("Y-m-d H:i:s", $time);
} catch (Exception|TypeError $e) {
    return false;
}

  • Das ist viel besser als die akzeptierte Antwort.

    – Nexarius

    19. Mai um 22:02 Uhr

  • Das ist viel besser als die akzeptierte Antwort.

    – Nexarius

    19. Mai um 22:02 Uhr

1346410cookie-checkphp: try-catch fängt nicht alle Ausnahmen ab

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

Privacy policy