PHP: Ausnahmen gegen Fehler?

116

Vielleicht fehlt es mir irgendwo im PHP-Handbuch, aber was genau ist der Unterschied zwischen einem Fehler und einer Ausnahme? Der einzige Unterschied, den ich sehen kann, ist, dass Fehler und Ausnahmen unterschiedlich behandelt werden. Aber was verursacht eine Ausnahme und was verursacht einen Fehler?

Jason Baker
quelle

Antworten:

87

Ausnahmen werden geworfen - sie sollen gefangen werden. Fehler können im Allgemeinen nicht behoben werden. Nehmen wir zum Beispiel an, Sie haben einen Codeblock, der eine Zeile in eine Datenbank einfügt. Es ist möglich, dass dieser Aufruf fehlschlägt (doppelte ID) - Sie möchten einen "Fehler" haben, der in diesem Fall eine "Ausnahme" ist. Wenn Sie diese Zeilen einfügen, können Sie so etwas tun

try {
  $row->insert();
  $inserted = true;
} catch (Exception $e) {
  echo "There was an error inserting the row - ".$e->getMessage();
  $inserted = false;
}

echo "Some more stuff";

Die Programmausführung wird fortgesetzt, da Sie die Ausnahme "abgefangen" haben. Eine Ausnahme wird als Fehler behandelt, sofern sie nicht abgefangen wird. Damit können Sie die Programmausführung fortsetzen, nachdem sie ebenfalls fehlgeschlagen ist.

Zwerg
quelle
29
Errors are generally unrecoverable<- eigentlich stimmt das nicht wirklich. E_ERRORund E_PARSEsind die beiden häufigsten nicht behebbaren Fehler (es gibt einige andere), aber die überwiegende Mehrheit der Fehler, die Sie in dev sehen, sind behebbar ( E_NOTICE, E_WARNINGet al.). Leider ist die Fehlerbehandlung von PHP ein komplettes Durcheinander - alle möglichen Dinge lösen unnötigerweise Fehler aus (zum Beispiel die überwiegende Mehrheit der Dateisystemfunktionen). Im Allgemeinen sind Ausnahmen "der OOP-Weg", aber leider verwenden einige der nativen OOP-APIs von PHP Fehler anstelle von Ausnahmen :-(
DaveRandom
1
@ DaveRandom E_NOTICE, E_WARNING sind per Definition keine "Fehler", oder? Ich habe sie immer als "Nachrichten" angesehen, die PHP anzeigt, um den Programmierer darüber zu informieren, dass möglicherweise etwas mit dem von ihm geschriebenen Code nicht stimmt.
Slhsen
2
@slhsen das Problem ist wirklich beschissene Terminologie, alle Formen dieser Nachrichten durchlaufen das "Fehlerbehandlungssystem" in PHP, semantisch sind alle diese Ereignisse "Fehler", obwohl semantisch Hinweis / Warnung definitiv nicht dasselbe ist wie ein " Fehler "in diesem Zusammenhang. Zum Glück hat das kommende PHP7 zumindest den Weg geebnet, dieses Durcheinander zu beseitigen, indem die meisten dieser Dinge in fangbare Ausnahmen umgewandelt wurden (mittels einer neuen ThrowableSchnittstelle), was eine viel ausdrucksstärkere und absolutere Möglichkeit bietet, beide Real zu unterscheiden und richtig zu übergeben Probleme und
Hinweise
"Programmausführung wird fortgesetzt" hat sich wohl geändert? Da PHP sagt "Wenn eine Ausnahme ausgelöst wird, wird Code, der der Anweisung folgt, nicht ausgeführt" ( php.net/manual/en/language.exceptions.php )
Robert Sinclair
1
Ich denke, was das OP bedeutete, war mehr über den Unterschied zwischen den Nachkommen von ErrorVS und den Nachkommen von Exception.
XedinUnknown
55

Ich set_error_handlergehe normalerweise zu einer Funktion, die den Fehler aufnimmt und eine Ausnahme auslöst, so dass ich, was auch immer passiert, nur Ausnahmen habe, mit denen ich mich befassen muss. Nicht mehr @file_get_contentsnur schön und ordentlich versuchen / fangen.

In Debug-Situationen habe ich auch einen Exception-Handler, der eine asp.net-ähnliche Seite ausgibt. Ich poste dies auf der Straße, aber wenn ich dazu aufgefordert werde, werde ich später eine Beispielquelle veröffentlichen.

bearbeiten:

Wie versprochen habe ich einen Teil meines Codes ausgeschnitten und eingefügt, um ein Beispiel zu erstellen. Ich habe das Folgende in einer Datei auf meiner Workstation gespeichert. Sie können die Ergebnisse hier NICHT MEHR sehen (da der Link unterbrochen ist).

<?php

define( 'DEBUG', true );

class ErrorOrWarningException extends Exception
{
    protected $_Context = null;
    public function getContext()
    {
        return $this->_Context;
    }
    public function setContext( $value )
    {
        $this->_Context = $value;
    }

    public function __construct( $code, $message, $file, $line, $context )
    {
        parent::__construct( $message, $code );

        $this->file = $file;
        $this->line = $line;
        $this->setContext( $context );
    }
}

/**
 * Inspire to write perfect code. everything is an exception, even minor warnings.
 **/
function error_to_exception( $code, $message, $file, $line, $context )
{
    throw new ErrorOrWarningException( $code, $message, $file, $line, $context );
}
set_error_handler( 'error_to_exception' );

function global_exception_handler( $ex )
{
    ob_start();
    dump_exception( $ex );
    $dump = ob_get_clean();
    // send email of dump to administrator?...

    // if we are in debug mode we are allowed to dump exceptions to the browser.
    if ( defined( 'DEBUG' ) && DEBUG == true )
    {
        echo $dump;
    }
    else // if we are in production we give our visitor a nice message without all the details.
    {
        echo file_get_contents( 'static/errors/fatalexception.html' );
    }
    exit;
}

function dump_exception( Exception $ex )
{
    $file = $ex->getFile();
    $line = $ex->getLine();

    if ( file_exists( $file ) )
    {
        $lines = file( $file );
    }

?><html>
    <head>
        <title><?= $ex->getMessage(); ?></title>
        <style type="text/css">
            body {
                width : 800px;
                margin : auto;
            }

            ul.code {
                border : inset 1px;
            }
            ul.code li {
                white-space: pre ;
                list-style-type : none;
                font-family : monospace;
            }
            ul.code li.line {
                color : red;
            }

            table.trace {
                width : 100%;
                border-collapse : collapse;
                border : solid 1px black;
            }
            table.thead tr {
                background : rgb(240,240,240);
            }
            table.trace tr.odd {
                background : white;
            }
            table.trace tr.even {
                background : rgb(250,250,250);
            }
            table.trace td {
                padding : 2px 4px 2px 4px;
            }
        </style>
    </head>
    <body>
        <h1>Uncaught <?= get_class( $ex ); ?></h1>
        <h2><?= $ex->getMessage(); ?></h2>
        <p>
            An uncaught <?= get_class( $ex ); ?> was thrown on line <?= $line; ?> of file <?= basename( $file ); ?> that prevented further execution of this request.
        </p>
        <h2>Where it happened:</h2>
        <? if ( isset($lines) ) : ?>
        <code><?= $file; ?></code>
        <ul class="code">
            <? for( $i = $line - 3; $i < $line + 3; $i ++ ) : ?>
                <? if ( $i > 0 && $i < count( $lines ) ) : ?>
                    <? if ( $i == $line-1 ) : ?>
                        <li class="line"><?= str_replace( "\n", "", $lines[$i] ); ?></li>
                    <? else : ?>
                        <li><?= str_replace( "\n", "", $lines[$i] ); ?></li>
                    <? endif; ?>
                <? endif; ?>
            <? endfor; ?>
        </ul>
        <? endif; ?>

        <? if ( is_array( $ex->getTrace() ) ) : ?>
        <h2>Stack trace:</h2>
            <table class="trace">
                <thead>
                    <tr>
                        <td>File</td>
                        <td>Line</td>
                        <td>Class</td>
                        <td>Function</td>
                        <td>Arguments</td>
                    </tr>
                </thead>
                <tbody>
                <? foreach ( $ex->getTrace() as $i => $trace ) : ?>
                    <tr class="<?= $i % 2 == 0 ? 'even' : 'odd'; ?>">
                        <td><?= isset($trace[ 'file' ]) ? basename($trace[ 'file' ]) : ''; ?></td>
                        <td><?= isset($trace[ 'line' ]) ? $trace[ 'line' ] : ''; ?></td>
                        <td><?= isset($trace[ 'class' ]) ? $trace[ 'class' ] : ''; ?></td>
                        <td><?= isset($trace[ 'function' ]) ? $trace[ 'function' ] : ''; ?></td>
                        <td>
                            <? if( isset($trace[ 'args' ]) ) : ?>
                                <? foreach ( $trace[ 'args' ] as $i => $arg ) : ?>
                                    <span title="<?= var_export( $arg, true ); ?>"><?= gettype( $arg ); ?></span>
                                    <?= $i < count( $trace['args'] ) -1 ? ',' : ''; ?> 
                                <? endforeach; ?>
                            <? else : ?>
                            NULL
                            <? endif; ?>
                        </td>
                    </tr>
                <? endforeach;?>
                </tbody>
            </table>
        <? else : ?>
            <pre><?= $ex->getTraceAsString(); ?></pre>
        <? endif; ?>
    </body>
</html><? // back in php
}
set_exception_handler( 'global_exception_handler' );

class X
{
    function __construct()
    {
        trigger_error( 'Whoops!', E_USER_NOTICE );      
    }
}

$x = new X();

throw new Exception( 'Execution will never get here' );

?>
Kris
quelle
Das wäre hilfreich. Alles, was mir hilft, mit PHP umzugehen, wird helfen. :-)
Jason Baker
Netter Code, danke. Ich verstehe allerdings nicht, woher die Klasse X kommt und wozu sie dient.
Alec
alles unter "set_exception_handler ('global_exception_handler');" ist nur eine Demo, Sie werden es nicht brauchen, es soll nur zeigen, was in einer normalerweise nicht ausnahmslosen Fehlersituation passieren würde.
Kris
Standard-PHP definiert ErrorException speziell für einen allgemeinen Fehlerbehandler. Würden Sie mir erlauben, Ihren Beitrag zu bearbeiten und zu aktualisieren?
Tiberiu-Ionuț Stan
@ Tiberiu-IonuțStan: Sicher, aber das Arbeitsbeispiel ist nicht synchron. Heutzutage würde ich wahrscheinlich auch Leute von private-void.com auf github.com/theredhead/red.web/blob/master/src/lib/bootstrap.php verweisen .
Kris
21

Die Antwort verdient es, über den Elefanten im Raum zu sprechen

Fehler ist die alte Methode zur Behandlung einer Fehlerbedingung zur Laufzeit. Normalerweise ruft der Code etwas auf, set_error_handlerbevor er Code ausführt. In Anlehnung an die Tradition der Assemblersprache unterbricht. So würde ein BASIC-Code aussehen.

on error :divide_error

print 1/0
print "this won't print"

:divide_error

if errcode = X
   print "divide by zero error"

Es war schwer sicherzustellen, dass set_error_handlerdies mit dem richtigen Wert aufgerufen wurde. Und noch schlimmer, es könnte ein Aufruf an eine separate Prozedur erfolgen, die den Fehlerbehandler ändern würde. Außerdem wurden Anrufe häufig mit set_error_handlerAnrufen und Handlern durchsetzt. Es war leicht für Code, schnell außer Kontrolle zu geraten. Die Ausnahmebehandlung wurde durch die Formalisierung der Syntax und Semantik dessen, was guter Code wirklich tat, behoben.

try {
   print 1/0;
   print "this won't print";
} catch (DivideByZeroException $e) {
   print "divide by zero error";
}

Keine separate Funktion oder das Risiko, den falschen Fehlerbehandler aufzurufen. Der Code befindet sich jetzt garantiert am selben Ort. Außerdem erhalten wir bessere Fehlermeldungen.

PHP hatte früher nur eine Fehlerbehandlung, als sich viele andere Sprachen bereits zum bevorzugten Modell für die Ausnahmebehandlung entwickelt hatten. Schließlich implementierten die Hersteller von PHP die Ausnahmebehandlung. Wahrscheinlich unterstützten sie alten Code, behielten jedoch die Fehlerbehandlung bei und boten eine Möglichkeit, die Fehlerbehandlung wie eine Ausnahmebehandlung aussehen zu lassen. Abgesehen davon gibt es keine Garantie dafür, dass ein Code den Fehlerbehandler möglicherweise nicht zurücksetzt, was genau das war, was die Ausnahmebehandlung bieten sollte.

Endgültige Antwort

Fehler, die vor der Implementierung der Ausnahmebehandlung codiert wurden, sind wahrscheinlich immer noch Fehler. Neue Fehler sind wahrscheinlich Ausnahmen. Es gibt jedoch kein Design oder keine Logik, bei denen es sich um Fehler und Ausnahmen handelt. Es basiert nur auf dem, was zum Zeitpunkt der Codierung verfügbar war, und der Präferenz des Programmierers, der es codiert.

Arturo Hernandez
quelle
3
Dies ist der wahre Grund, warum Ausnahmen und Fehler nebeneinander existieren. Wenn von Grund auf neu entwickelt, sollte PHP nur das eine oder andere enthalten.
Tomas Zubiri
1
Es ist meiner Meinung nach die beste Antwort, da es die detaillierteste und erklärendste ist.
Robert Kusznier
8

Eine Sache, die hier hinzugefügt werden muss, ist die Behandlung von Ausnahmen und Fehlern. Für den Anwendungsentwickler sind sowohl Fehler als auch Ausnahmen "schlechte Dinge", die Sie aufzeichnen möchten, um mehr über die Probleme Ihrer Anwendung zu erfahren - damit Ihre Kunden auf lange Sicht eine bessere Erfahrung haben.

Es ist daher sinnvoll, einen Fehlerbehandler zu schreiben, der das Gleiche tut wie Sie für Ausnahmen.

Alex Weinstein
quelle
Vielen Dank für die Bereitstellung des Links!
Mike Moore
@ Alex Weinstein: Die Verbindung ist unterbrochen
Marco Demaio
7

Wie in anderen Antworten angegeben, ist die Einstellung des Fehlerbehandlers auf den Ausnahmewerfer der beste Weg, um Fehler in PHP zu behandeln. Ich benutze ein etwas einfacheres Setup:

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

Bitte beachten Sie die error_reporting() Überprüfung, damit der @Bediener weiterarbeitet. Es ist auch nicht erforderlich, eine benutzerdefinierte Ausnahme zu definieren. PHP hat dafür eine nette Klasse.

Der große Vorteil des Auslösens von Ausnahmen besteht darin, dass der Ausnahme eine Stapelverfolgung zugeordnet ist, sodass leicht festgestellt werden kann, wo das Problem liegt.

Josef Kufner
quelle
5

Betreff: "Aber was genau ist der Unterschied zwischen einem Fehler und einer Ausnahme?"

Es gibt viele gute Antworten auf die Unterschiede hier. Ich werde nur etwas hinzufügen, über das noch nicht gesprochen wurde - Leistung. Dies gilt insbesondere für den Unterschied zwischen dem Auslösen / Behandeln von Ausnahmen und dem Behandeln eines Rückkehrcodes (entweder Erfolg oder Fehler). In PHP bedeutet dies normalerweise das Zurückgeben von falseoder null, aber sie können detaillierter sein, z. B. beim Hochladen von Dateien: http://php.net/manual/en/features.file-upload.errors.php Sie können sogar ein Exception-Objekt zurückgeben !

Ich habe einige Performance-Läufe in verschiedenen Sprachen / Systemen durchgeführt. Im Allgemeinen ist die Ausnahmebehandlung etwa 10.000-mal langsamer als die Suche nach einem Fehlerrückgabecode.

Wenn es also unbedingt die Ausführung beenden muss, bevor es überhaupt begonnen hat - nun, Sie haben kein Glück, weil es keine Zeitreisen gibt. Ohne Zeitreise sind Rückkehrcodes die schnellste verfügbare Option.

Bearbeiten:

PHP ist stark für die Ausnahmebehandlung optimiert. Tests in der Praxis zeigen, dass das Auslösen einer Ausnahme nur 2-10x langsamer ist als das Zurückgeben eines Werts.

evan
quelle
3
Sicher, aber die Anzahl der Zyklen, die durch das Auslösen von Ausnahmen verloren gehen, wird durch die zusätzlichen beschreibenden Kräfte, die Sie mit Ausnahmen erhalten, mehr als wettgemacht. Sie können bestimmte Arten von Ausnahmen auslösen und der Ausnahme sogar Daten hinzufügen, um die Fehlercodes zu enthalten. Ich bezweifle ernsthaft Ihre 10.000 * Behauptung. Selbst wenn Sie mit dem Zeitunterschied Recht haben, ist die Zeit, die Sie für die Rückgabe und die Neuausführung, das Werfen und das Fangen in einem realen Szenario aufgewendet haben, im Vergleich zum ausgeführten Code wahrscheinlich so winzig, dass dies definitiv eine vorzeitige Optimierung ist. Mit Ausnahmen sind sie in 90% der Fälle besser zu handhaben.
Gnarf
1
1. 10.000x ist genau - mit einigen Abweichungen basierend auf Sprach- und Compileroptionen. 2. Sie müssen nicht null / false zurückgeben. Sie können eine Nummer zurückgeben - bis zu den MAX_ULONG-Rückkehrcodes direkt dort. Sie können alternativ eine Fehlerzeichenfolge zurückgeben und einfach nach einer Erfolgszeichenfolge oder int oder null suchen. 3. In realen Szenarien zählt jeder Taktzyklus. Facebook hat täglich 552 Millionen aktive Nutzer. Angenommen, es gibt nur zwei Ausnahmen, und die Überprüfung von Benutzer / Pass dauert 0,001 Sekunden, was bedeutet, dass täglich 153 Stunden Verarbeitungszeit eingespart werden. Bei 10.000x spart es 175 Jahre. Nur um Anmeldeversuche zu überprüfen - jeden Tag.
Evans
@evan: FYI, hier haben sie Code mit Ausnahmen getestet und es scheint nicht langsamer zu sein: stackoverflow.com/a/445094/260080
Marco Demaio
@MarcoDemaio Diese Frage behandelt nur den Try / Catch-Block, ohne eine Ausnahme auszulösen. Ein besserer Test wäre, einen Wert in noexcept () zurückzugeben und eine Ausnahme in Ausnahme () auszulösen. Außerdem sollte es durch mehrere Funktionen sprudeln. stackoverflow.com/a/104375/505172 gibt an, dass der Unterschied in PHP tatsächlich 54x beträgt. Ich habe meinen eigenen Test in Echtzeit durchgeführt und er scheint 2-10x langsamer zu sein. Das ist viel besser als erwartet.
Evans
@evan: Ich würde mir dann keine Sorgen machen, ich verwende Ausnahmen nur, um unerwartete / nicht behebbare Fehler zu verfolgen. Selbst wenn es 100-mal langsamer wäre, wäre es mir egal. Meine Sorge war, den Code durch einfaches Hinzufügen von Try / Catch-Blöcken zu verlangsamen.
Marco Demaio
4

Ich denke, die Antwort, die Sie suchen, ist die;

Fehler sind das Standardmaterial, an das Sie gewöhnt sind, z. B. das Echo einer nicht vorhandenen $ -Variablen.
Ausnahmen gelten nur ab PHP 5 und treten beim Umgang mit Objekten auf.

Um es einfach zu halten:

Ausnahmen sind die Fehler, die beim Umgang mit Objekten auftreten. Mit der try / catch-Anweisung können Sie jedoch etwas dagegen tun. Sie wird ähnlich wie die if / else-Anweisung verwendet. Versuchen Sie dies zu tun, wenn das Problem keine Rolle spielt, tun Sie dies.

Wenn Sie eine Ausnahme nicht "abfangen", wird sie zu einem Standardfehler.

Fehler sind die grundlegenden PHP-Fehler, die normalerweise Ihr Skript anhalten.

Try / Catch wird häufig zum Herstellen von Datenbankverbindungen wie PDO verwendet. Dies ist in Ordnung, wenn Sie das Skript umleiten oder etwas anderes tun möchten, wenn die Verbindung nicht funktioniert. Wenn Sie jedoch nur die Fehlermeldung anzeigen und das Skript stoppen möchten, benötigen Sie sie nicht. Die nicht erfasste Ausnahme wird zu einem schwerwiegenden Fehler. Sie können auch eine standortweite Fehlerbehandlungseinstellung verwenden.

hoffentlich hilft das

Lan
quelle
3
Ausnahmen können genauso gut mit prozeduralem Code in PHP verwendet werden.
Tiberiu-Ionuț Stan
2

In PHP 7.1 und höher kann ein catch- Block mehrere Ausnahmen mithilfe des Pipe-Zeichens (|) angeben. Dies ist nützlich, wenn verschiedene Ausnahmen aus verschiedenen Klassenhierarchien gleich behandelt werden.

try {
  // do something
} catch (Error | Exception $e) {
  echo $e->getMessage();
}
Jehong Ahn
quelle
1

Ausnahmen werden absichtlich durch Code mit einem Wurf ausgelöst, Fehler ... nicht so sehr.

Fehler entstehen durch etwas, das normalerweise nicht behandelt wird. (E / A-Fehler, TCP / IP-Fehler, Nullreferenzfehler)

cgp
quelle
1
Dies ist nicht unbedingt wahr. In vielen Fällen werden Fehler überprüft und Rückgabecodes absichtlich zurückgesendet. Tatsächlich ist dies für jede nicht objektorientierte Sprache der Fall. Ausnahmen sind genau das, Ausnahmen von der Regel. In beiden Fällen geht etwas schief, wird bemerkt und sollte behandelt werden. Das Hochladen von PHP-Dateien ist ein Beispiel für die absichtliche Fehlerbehandlung über Rückkehrcodes - php.net/manual/en/features.file-upload.errors.php
Uhr
1

Ich beabsichtige, Ihnen eine äußerst ungewöhnliche Diskussion über die Fehlerkontrolle zu geben.

Ich habe vor Jahren einen sehr guten Fehlerbehandler in eine Sprache eingebaut, und obwohl sich einige Namen geändert haben, sind die Prinzipien der Fehlerverarbeitung heute dieselben. Ich hatte ein speziell entwickeltes Multitasking-Betriebssystem und musste in der Lage sein, Datenfehler auf allen Ebenen ohne Speicherlecks, Stapelwachstum oder Abstürze zu beheben. Was folgt, ist mein Verständnis, wie Fehler und Ausnahmen funktionieren müssen und wie sie sich unterscheiden. Ich werde nur sagen, dass ich nicht verstehe, wie die Interna von try catch funktionieren, also rate ich bis zu einem gewissen Grad.

Das erste, was bei der Fehlerverarbeitung unter der Decke passiert, ist das Springen von einem Programmstatus in einen anderen. Wie geht das? Ich werde dazu kommen.

In der Vergangenheit sind Fehler älter und einfacher, und Ausnahmen sind neuer und etwas komplexer und leistungsfähiger. Fehler funktionieren einwandfrei, bis Sie sie in die Luft sprengen müssen. Dies entspricht der Übergabe eines schwierigen Problems an Ihren Vorgesetzten.

Fehler können Zahlen sein, wie Fehlernummern, und manchmal mit einer oder mehreren zugeordneten Zeichenfolgen. Wenn beispielsweise ein Fehler beim Lesen von Dateien auftritt, können Sie möglicherweise melden, was es ist, und möglicherweise ordnungsgemäß fehlschlagen. (Hay, es ist ein Schritt nach dem Absturz wie früher.)

Über Ausnahmen wird nicht oft gesagt, dass Ausnahmen Objekte sind, die auf einem speziellen Ausnahmestapel liegen. Es ist wie ein Rückgabestapel für den Programmablauf, enthält jedoch einen Rückgabestatus nur für Fehlerversuche und -fänge. (Früher nannte ich sie ePush und ePop, und? Abort war ein bedingter Wurf, der ePop und Wiederherstellung auf dieses Niveau brachte, während Abort ein voller Würfel oder Exit war.)

Am unteren Rand des Stapels befinden sich die Informationen zum ersten Aufrufer, dem Objekt, das den Status kennt, als der äußere Versuch gestartet wurde, häufig als Ihr Programm gestartet wurde. Darüber hinaus ist die nächste Ebene auf dem Stapel, wobei up die Kinder und down die Eltern sind, das Ausnahmeobjekt des nächsten inneren try / catch-Blocks.

Wenn Sie einen Versuch in einen Versuch einfügen, stapeln Sie den inneren Versuch über den äußeren Versuch. Wenn im inneren Versuch ein Fehler auftritt und entweder der innere Fang ihn nicht verarbeiten kann oder der Fehler in den äußeren Versuch geworfen wird, wird die Steuerung an den äußeren Fangblock (Objekt) übergeben, um zu prüfen, ob er den Fehler behandeln kann, d. H. Ihr Vorgesetzter.

Dieser Fehlerstapel ist also wirklich in der Lage, den Programmfluss und den Systemstatus zu markieren und wiederherzustellen. Mit anderen Worten, er ermöglicht es einem Programm, den Rückgabestapel nicht zum Absturz zu bringen und Dinge für andere (Daten) durcheinander zu bringen, wenn etwas schief geht. Auf diese Weise wird auch der Status anderer Ressourcen wie Speicherzuweisungspools gespeichert und diese können nach Abschluss des Abfangens bereinigt werden. Im Allgemeinen kann dies eine sehr komplizierte Sache sein, und deshalb ist die Ausnahmebehandlung oft langsam. Im Allgemeinen muss einiges an Status in diese Ausnahmeblöcke gehen.

Ein Try / Catch-Block setzt also einen Zustand, in den er zurückkehren kann, wenn alles andere durcheinander kommt. Es ist wie bei einem Elternteil. Wenn unser Leben durcheinander gerät, können wir in den Schoß unserer Eltern zurückfallen und sie werden alles wieder in Ordnung bringen.

Hoffe ich habe dich nicht enttäuscht.

Elliptische Ansicht
quelle
1

Sie können diesen Kommentar hinzufügen

function doSomething()
{
   /** @noinspection PhpUnhandledExceptionInspection */
   throw new Exception();
}
Yolo
quelle
0

Sobald set_error_handler () definiert ist, ähnelt der Fehlerhandler dem von Exception. Siehe Code unten:

 <?php
 function handleErrors( $e_code ) {
   echo "error code: " . $e_code . "<br>";
 }

 set_error_handler( "handleErrors" ); 

 trigger_error( "trigger a fatal error", E_USER_ERROR);
 echo "after error."; //it would run if set_error_handler is defined, otherwise, it wouldn't show
?>
N Zhang
quelle