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.
Errors are generally unrecoverable
<- eigentlich stimmt das nicht wirklich.E_ERROR
undE_PARSE
sind 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_WARNING
et 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 :-(