Heim > Artikel > Backend-Entwicklung > Details und Beispiele zum Ausnahme- und Fehlerhandler in PHP
Vorwort
Im aktuellen Projekt muss eine Funktion implementiert werden: Im Debugging-Modus werden alle Fehler im Voraus ausgegeben und dann der Seiteninhalt ausgegeben.
Um die oben genannte Funktion zu erreichen, müssen Sie Ausnahme- und fehlerbezogene Handlermethoden verwenden und viele Fallstricke finden. Deshalb habe ich diesen Artikel geschrieben, um ihn mit Ihnen zu teilen
Empfohlenes PHP-Video-Tutorial: https://www.php.cn/course/list/29/type/2.html
Hauptfunktionen
Dieser Artikel konzentriert sich auf die folgende Funktionen
1,error_reporting()
2, set_error_handler()
3, set_exception_handler()
4, register_shutdown_function()
5, error_get_last()
Der folgende Artikel konzentriert sich auf eine Liste von Fragen:
1. Welche Verbindung besteht zwischen error_reporting()
und error_get_last()
?
2. set_error_handler()
ist an set_exception_handler()
handler
gebunden. Wie hängen sie zusammen?
3. Hängt register_shutdown_function()
normalerweise mit Exception/Error
zusammen?
Fragenlösung:
1. Was ist der Zusammenhang zwischen error_reporting()
und error_get_last()
?
Link: php.net - error_reporting()
<br>Link: php.net - error_get_last()
a:int error_reporting ([ int $level ] )
Jeder sollte damit vertraut sein, deshalb werde ich nicht auf Details eingehen
b: array error_get_last ( void )
Get Der zuletzt aufgetretene Fehler
wird normalerweise verwendet, um einen schwerwiegenden Fehler während der Ausführung von PHP zu erhalten (PHP 5).
Die beiden Funktionen sind wörtlich nicht eng miteinander verbunden, aber bitte beachten Sie den folgenden Code Ausgabe
<?php error_reporting(E_ALL & ~E_NOTICE); $a = $b; //E_NOTICEprint_r(error_get_last());/* output: Array ( [type] => 8 [message] => Undefined variable: b [file] => /app/t.php [line] => 3 ) */
error_get_last()
Obwohl es die Erfassung des letzten Vorkommens veranschaulicht, ist es tatsächlich dasselbe. Es erklärt jedoch nicht, ob von error_reporting()
ignorierte Fehler erhalten werden können Wenn wir error_get_last()
verwenden, müssen wir auf Fehler achten, die normalerweise ignoriert werden, wie zum Beispiel: E_DEPRECATED
2. Welche Verbindung besteht zwischen set_error_handler()
? set_exception_handler()
handler
Link:
Link: php.net - set_error_handler()
<br>php.net - set_exception_handler()
a,
mixed set_error_handler ( callable $error_handler [, int $error_types = E_ALL | E_STRICT ] )
Benutzerdefinierte Fehlerbehandlungsfunktion festlegen
<br>Wird normalerweise ausgelöst, wenn während der Ausführung von PHP-Skripten einige unterbrechungsfreie Fehler auftreten.
Wir verwenden dies, um Fehlerprotokolle oder direkte Ausgaben und andere Vorgänge aufzuzeichnen.<br>
Hinweis:FALSE: Die Standard-Fehlerbehandlung wird weiterhin durchgeführt (die Standard-Fehlerbehandlung hängt von
ab, um zu entscheiden, ob nach ausgegeben werden soll) display_errors = true/false
stderr
1. Der Parameter
, es wird jedoch empfohlen, es auf $error_types
zu setzen. Insbesondere, welche Fehler verarbeitet werden müssen, ist es offensichtlich flexibler, zu beurteilen, welche im Handler nicht benötigt werden.error_reporting()
2、以下级别的错误不能由用户定义的函数来处理: E_ERROR
、 E_PARSE
、 E_CORE_ERROR
、 E_CORE_WARNING
、 E_COMPILE_ERROR
、 E_COMPILE_WARNING
,和在 调用 set_error_handler()
函数所在文件中产生的大多数 E_STRICT
3、handler被触发后, 并不会中断PHP运行.
4、bool error_handler ( int $errno , string $errstr [, string $errfile [, int $errline [, array $errcontext ]]] )
<br>注意error_handler
的返回值:
b、callable set_exception_handler ( callable $exception_handler )
设置用户自定义的异常处理函数<br>设置默认的异常处理程序,用于没有用 try
/catch
块来捕获的异常。 在 exception_handler
调用后异常会中止。
注意:
注意点中2, 3项轻描淡写了一下PHP 5/PHP 7之间的不同却透露出重要的消息(坑..)<br>PHP 7中, exception_handler
不再只接受Exception
了, 并且接收了Error
错误.<br>link: php.net - PHP7 Errors
列表
1、exception_handler
调用后异常会中止(脚本终止).
2、PHP 5, PHP 7的exception_handler
并不相同.<br>PHP 5: void handler ( Exception $ex )
<br>PHP 7: void handler ( Throwable $ex )
3、自 PHP 7 以来,大多数错误抛出 Error
异常,也能被捕获。 Error
和 Exception
都实现了 Throwable 接口。
因此, set_error_handler()
与 set_exception_handler()
之间的关系也迎刃而解:<br>
PHP 5:
1、set_error_handler()
: 负责非中断行错误.
2、set_exception_handler()
: 负责没有被catch的异常(会中断).
3、Fatal Error
等: 并不会被两者管理, 正常输出到屏幕上(弊端).
PHP 7:
1、set_error_handler()
: 负责非中断行错误.
2、set_exception_handler()
: 负责没有被catch的异常, Error(会中断)
3、Fatal Error
等: 由set_exception_handler()
管理.
3. register_shutdown_function()
通常跟Exception
/Error
有关系么?
link: php.net - register_shutdown_function()
注册一个 callback ,它会在脚本执行完成或者 exit() 后被调用。
根据说明可以得出结论, 它与Exception
/Error
完全没关系.<br>提出这个问题, 主要是因为, 在PHP5中Fatal Error
并没有明确的接收地点, 所以我们通常配合error_get_last()
来接收Fatal Error
<?php register_shutdown_function('shutdown_function'); unknown_function();function shutdown_function() { print_r(error_get_last()); }/* output:Array( [type] => 1 [message] => Uncaught Error: Call to undefined function unknown_function() in /app/t.php:3Stack trace:#0 {main} thrown [file] => /app/t.php [line] => 3) */
然而随着PHP 7的到来, Error已经可以被set_exception_handler()
捕捉了, 再通过error_get_last()
就多余了. shutdown中更多的是一些版本冗余的工作.<br>
实例
前言中的需求: 调试模式下, 将所有错误提前输出, 再输出页面内容.<br>以下是demo, 省去了环境判断(debug环境), 大家可以根据下面这段代码, 了解本文中所说的各种handler的触发和调用情况.
<?php/* 要求: 将所有异常打印在屏幕最上方 *//* Fatal Error 中断脚本 -> shutdown_handler *///设置错误级别define("END_ERRORS", '--END ERRORS--' . PHP_EOL . PHP_EOL); ini_set('display_errors', true); ini_set('error_reporting', E_ALL & ~E_DEPRECATED); set_error_handler('usr_err_handler', error_reporting()); //注册错误处理函数set_exception_handler('usr_ex_handler'); //注册异常处理函数register_shutdown_function('shutdown_handler'); //注册会在php中止时执行的函数$global_errors = []; //用于记录所有错误$errnos = [ //错误级别 0 => 'ERROR',//PHP7 ERROR的CODE 1 => 'E_ERROR',//FATAL ERROR(PHP5), E_ERROR 2 => 'E_WARNING', 4 => 'E_PARSE', 8 => 'E_NOTICE', 16 => 'E_CORE_ERROR', 32 => 'E_CORE_WARNING', 64 => 'E_COMPILE_ERROR', 128 => 'E_COMPILE_WARNING', 256 => 'E_USER_ERROR', 512 => 'E_USER_WARNING', 1024 => 'E_USER_NOTICE', 2048 => 'E_STRICT', 4096 => 'E_RECOVERABLE_ERROR', 8192 => 'E_DEPRECATED', 16384 => 'E_USER_DEPRECATED', 30719 => 'E_ALL', ];function reset_errors(){ global $global_errors; $global_errors = []; }function get_errnostr($errno){ global $errnos; return $errnos[$errno]; }function set_errnos($errno, $errstr){ global $global_errors; $global_errors[] = [ 'errno' => $errno, 'errnostr' => get_errnostr($errno), 'errstr' => $errstr, ]; }function print_errors($prefix){ global $global_errors; foreach ($global_errors as $err) {//由于handler中依然有可能有error 因此放最后 printf("[%s]: %s, %d, %s\n", $prefix, $err['errnostr'], $err['errno'], $err['errstr']); } }//用户异常处理函数 (进来就中断脚本) PHP5只有Exception进来 PHP7Error和Exception//PHP7中 void handler (Throwable $ex) 可捕获Error和Exception两种异常, 暂不管//http://php.net/manual/en/language.errors.php7.php PHP7 Error阅读//内部如果有Error则触发Error函数, 再回到错误行继续执行function usr_ex_handler($ex){ $content = ob_get_clean(); //让Exception/Error提前展示 print_errors('EX ERROR'); reset_errors(); $errnostr = get_errnostr($ex->getCode()); $errno = $ex->getCode(); $errstr = $ex->getMessage(); if ($ex instanceof Exception) { printf("[EXCEPTION]: %s, %d, %s\n", $errnostr, $errno, $errstr); } else {//针对PHP7 $ex instanceof Error printf("[EX FATAL ERROR]: %s, %d, %s\n", $errnostr, $errno, $errstr); } //由于handler中依然有可能有error 因此放最后 print_errors('EX ERROR'); reset_errors(); echo END_ERRORS; echo $content; return; }//用户错误处理函数//E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING不能被用户处理function usr_err_handler($errno, $errstr, $errfile, $errline, $errcontext){ set_errnos($errno, $errstr); return true; //如果函数返回 FALSE,标准错误处理处理程序将会继续调用。}//用户PHP终止函数function shutdown_handler(){ $content = ob_get_clean(); //让Exception/Error提前展示 $err = error_get_last();//检查一下是否有遗漏掉的错误 php5 fatal error if ($err['type'] & error_reporting()) { set_errnos($err['type'], $err['message']); } print_errors('ST ERROR'); reset_errors(); echo $content; } ob_start();echo 'Main function...', PHP_EOL;//搞事情//throw new Exception('这是一个异常');trigger_error('这是一个用户error');//E_USER_NOTICEif (version_compare(PHP_VERSION, '7.0.0') >= 0) { mcrypt_encrypt();//E_WARNING, E_DEPRECATED} else { mysql(); } unknown_function(); //fatal error$content = ob_get_clean();//优先输出错误print_errors('MA ERROR');if (!empty($global_errors)) { echo END_ERRORS; } reset_errors();//输出正文内容echo $content;
以上就是全部内容了,更多相关问题请访问PHP中文网:https://www.php.cn/<br>
Das obige ist der detaillierte Inhalt vonDetails und Beispiele zum Ausnahme- und Fehlerhandler in PHP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!