PHP原理之异常机制深入分析_PHP教程
PHP的异常机制的原理是什么?
在PHP每一个可独立执行的op array最后的ZEND_HANDLE_EXCEPTION是用来干什么呢?
让我们从一个问题说起, 上周的时候, blue5tar提了一个问题:”对于下面的代码, onError明明执行了, 但是onException却没有执行, 为什么?”.
function onError($errCode, $errMesg, $errFile, $errLine) {
echo "Error Occurred\n";
throw new Exception($errMesg);
}
function onException($e) {
echo $e->getMessage();
}
set_error_handler("onError");
set_exception_handler("onException");
/* 我从不会以我的名字命名文件, 所以这个文件不存在 */
require("laruence.php");
运行结果:
Error Occurred
PHP Fatal error: main(): Failed opening required 'laruence.php
首先, 我们要知道, Require在包含一个找不到的问题的时候, 会前后抛出俩个错误,
1. WARNING : 在PHP试图打开这个文件的时候抛出.
2. E_COMPILE_ERROR : 从PHP打开文件的函数返回失败以后抛出
而我们知道, set_error_handler是不能捕获E_COMPILE_ERROR错误的:
The following error types cannot be handled with a user defined function: E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, and most of E_STRICT raised in the file where set_error_handler() is called.
所以, 在onError中, 只能捕获到第一个WARNING错误, 而在onError中抛出的异常, 为什么没有被默认exception_handler捕获呢?
这就要说说PHP的异常机制了.
了解opcode(深入理解PHP原理之Opcodes的同学都知道, 在PHP5.3以前, 每一个可独立运行的op array(文件, 函数, 方法)的最后一条opcode都是ZEND_HANDLE_EXCEPTION, 而这个opcode是做什么用的呢?
原来在PHP中, 当有异常被throw的时候, 会跳到每一个op array的最后一行, 来执行这条ZEND_HANDLE_EXCEPTION, 伪码如下:
void on_throw_exception(zval *exception TSRMLS_DC) {
1. 判断是否已经有异常抛出
2. 记录exception
3. 记录下一条要执行的op line的序号
4. 下一条要执行的op line序号 = 当前op array的最后一条
}
恩, 就和改写ip寄存器一样, 改写下一条要执行的op line的序号, 就改变了程序的流向, 这样, 就会进入到了ZEND_HANDLE_EXCEPTION的处理逻辑中.
而在ZEND_HANDLE_EXCEPTION中, 会判断这个异常是否在try catch中,
如果是 则把下一条要执行的op line, 置为第一个catch的op line, 并继续执行.
如果不是 则销毁一些不需要的变量, 和opline, 然后直接结束执行过程
有的同学要问了:”那set_exception_handler设置的异常默认处理函数(user_exception_handler)什么时候起作用呢?”
恩, 是在执行完成退出执行LOOP以后才判断是否有默认异常处理函数, 如果有才调用:
//执行
zend_execute(EG(active_op_array) TSRMLS_CC);
if (EG(exception)) {
if (EG(user_exception_handler)) {
调用用户定义的默认异常处理函数
} else {
未捕获的异常
}
} else {
没有异常
}
destroy_op_array(EG(active_op_array) TSRMLS_CC);
efree(EG(active_op_array));

PHP异常流程
而PHP在遇到Fatal Error的时候, 会直接zend_bailout, 而zend_bailout会导致程序流程直接跳过上面代码段, 也可以理解为直接exit了(longjmp), 这就导致了user_exception_handler没有机会发生作用.
了解到这些, 我想文章开头的问题的为什么? 也就很清晰了吧?
最后, 关于ZEND_HANDLE_EXCEPTION, 也许有同学会有疑问: 如果是这样, 那为什么每一个可独立执行的op array最后都有这个ZEND_HANDLE_EXCEPTION呢? 最简单的, 如果一个函数中不会throw, 那么这个opcode 是明显不需要的啊? 嘿嘿, 你很聪明, PHP 5.3开始, 已经按照你的想法调整了.. 只有在throw时刻, 才会动态的生成ZEND_HANDLE_EXCEPTION opline.
PHP5 changelog:
Changed exception handling. Now each op_array doesn't contain ZEND_HANDLE_EXCEPTION opcode in the end. (Dmitry)

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



PHP 8.4 bringt mehrere neue Funktionen, Sicherheitsverbesserungen und Leistungsverbesserungen mit einer beträchtlichen Menge an veralteten und entfernten Funktionen. In dieser Anleitung wird erklärt, wie Sie PHP 8.4 installieren oder auf PHP 8.4 auf Ubuntu, Debian oder deren Derivaten aktualisieren. Obwohl es möglich ist, PHP aus dem Quellcode zu kompilieren, ist die Installation aus einem APT-Repository wie unten erläutert oft schneller und sicherer, da diese Repositorys in Zukunft die neuesten Fehlerbehebungen und Sicherheitsupdates bereitstellen.

Visual Studio Code, auch bekannt als VS Code, ist ein kostenloser Quellcode-Editor – oder eine integrierte Entwicklungsumgebung (IDE) –, die für alle gängigen Betriebssysteme verfügbar ist. Mit einer großen Sammlung von Erweiterungen für viele Programmiersprachen kann VS Code c

Wenn Sie ein erfahrener PHP-Entwickler sind, haben Sie möglicherweise das Gefühl, dass Sie dort waren und dies bereits getan haben. Sie haben eine beträchtliche Anzahl von Anwendungen entwickelt, Millionen von Codezeilen debuggt und eine Reihe von Skripten optimiert, um op zu erreichen

Dieses Tutorial zeigt, wie XML -Dokumente mit PHP effizient verarbeitet werden. XML (Extensible Markup-Sprache) ist eine vielseitige textbasierte Markup-Sprache, die sowohl für die Lesbarkeit des Menschen als auch für die Analyse von Maschinen entwickelt wurde. Es wird üblicherweise für die Datenspeicherung ein verwendet und wird häufig verwendet

JWT ist ein offener Standard, der auf JSON basiert und zur sicheren Übertragung von Informationen zwischen Parteien verwendet wird, hauptsächlich für die Identitätsauthentifizierung und den Informationsaustausch. 1. JWT besteht aus drei Teilen: Header, Nutzlast und Signatur. 2. Das Arbeitsprinzip von JWT enthält drei Schritte: Generierung von JWT, Überprüfung von JWT und Parsingnayload. 3. Bei Verwendung von JWT zur Authentifizierung in PHP kann JWT generiert und überprüft werden, und die Funktionen und Berechtigungsinformationen der Benutzer können in die erweiterte Verwendung aufgenommen werden. 4. Häufige Fehler sind Signaturüberprüfungsfehler, Token -Ablauf und übergroße Nutzlast. Zu Debugging -Fähigkeiten gehört die Verwendung von Debugging -Tools und Protokollierung. 5. Leistungsoptimierung und Best Practices umfassen die Verwendung geeigneter Signaturalgorithmen, das Einstellen von Gültigkeitsperioden angemessen.

Eine Zeichenfolge ist eine Folge von Zeichen, einschließlich Buchstaben, Zahlen und Symbolen. In diesem Tutorial wird lernen, wie Sie die Anzahl der Vokale in einer bestimmten Zeichenfolge in PHP unter Verwendung verschiedener Methoden berechnen. Die Vokale auf Englisch sind a, e, i, o, u und sie können Großbuchstaben oder Kleinbuchstaben sein. Was ist ein Vokal? Vokale sind alphabetische Zeichen, die eine spezifische Aussprache darstellen. Es gibt fünf Vokale in Englisch, einschließlich Großbuchstaben und Kleinbuchstaben: a, e, ich, o, u Beispiel 1 Eingabe: String = "TutorialPoint" Ausgabe: 6 erklären Die Vokale in der String "TutorialPoint" sind u, o, i, a, o, ich. Insgesamt gibt es 6 Yuan

Statische Bindung (statisch: :) implementiert die späte statische Bindung (LSB) in PHP, sodass das Aufrufen von Klassen in statischen Kontexten anstatt Klassen zu definieren. 1) Der Analyseprozess wird zur Laufzeit durchgeführt.

Was sind die magischen Methoden von PHP? Zu den magischen Methoden von PHP gehören: 1. \ _ \ _ Konstrukt, verwendet, um Objekte zu initialisieren; 2. \ _ \ _ Destruct, verwendet zur Reinigung von Ressourcen; 3. \ _ \ _ Call, behandeln Sie nicht existierende Methodenaufrufe; 4. \ _ \ _ GET, Implementieren Sie den dynamischen Attributzugriff; 5. \ _ \ _ Setzen Sie dynamische Attributeinstellungen. Diese Methoden werden in bestimmten Situationen automatisch aufgerufen, wodurch die Code -Flexibilität und -Effizienz verbessert werden.
