Heim  >  Artikel  >  Backend-Entwicklung  >  Details und Beispiele zum Ausnahme- und Fehlerhandler in PHP

Details und Beispiele zum Ausnahme- und Fehlerhandler in PHP

王林
王林nach vorne
2019-08-20 09:58:223121Durchsuche

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() handlerLink:

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/falsestderr 1. Der Parameter

ist größtenteils gesetzt auf

, 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_PARSEE_CORE_ERRORE_CORE_WARNING E_COMPILE_ERRORE_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(&#39;shutdown_function&#39;);
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", &#39;--END ERRORS--&#39; . PHP_EOL . PHP_EOL);
ini_set(&#39;display_errors&#39;, true);
ini_set(&#39;error_reporting&#39;, E_ALL & ~E_DEPRECATED);

set_error_handler(&#39;usr_err_handler&#39;, error_reporting()); //注册错误处理函数set_exception_handler(&#39;usr_ex_handler&#39;); //注册异常处理函数register_shutdown_function(&#39;shutdown_handler&#39;);    //注册会在php中止时执行的函数$global_errors = [];    //用于记录所有错误$errnos = [             //错误级别
    0 => &#39;ERROR&#39;,//PHP7 ERROR的CODE
    1 => &#39;E_ERROR&#39;,//FATAL ERROR(PHP5), E_ERROR
    2 => &#39;E_WARNING&#39;,    4 => &#39;E_PARSE&#39;,    8 => &#39;E_NOTICE&#39;,    16 => &#39;E_CORE_ERROR&#39;,    32 => &#39;E_CORE_WARNING&#39;,    64 => &#39;E_COMPILE_ERROR&#39;,    128 => &#39;E_COMPILE_WARNING&#39;,    256 => &#39;E_USER_ERROR&#39;,    512 => &#39;E_USER_WARNING&#39;,    1024 => &#39;E_USER_NOTICE&#39;,    2048 => &#39;E_STRICT&#39;,    4096 => &#39;E_RECOVERABLE_ERROR&#39;,    8192 => &#39;E_DEPRECATED&#39;,    16384 => &#39;E_USER_DEPRECATED&#39;,    30719 => &#39;E_ALL&#39;,
];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[] = [        &#39;errno&#39; => $errno,        &#39;errnostr&#39; => get_errnostr($errno),        &#39;errstr&#39; => $errstr,
    ];
}function print_errors($prefix){    global $global_errors;    foreach ($global_errors as $err) {//由于handler中依然有可能有error 因此放最后
        printf("[%s]: %s, %d, %s\n",
            $prefix, $err[&#39;errnostr&#39;], $err[&#39;errno&#39;], $err[&#39;errstr&#39;]);
    }
}//用户异常处理函数 (进来就中断脚本) 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(&#39;EX ERROR&#39;);
    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(&#39;EX ERROR&#39;);
    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[&#39;type&#39;] & error_reporting()) {
        set_errnos($err[&#39;type&#39;], $err[&#39;message&#39;]);
    }
    print_errors(&#39;ST ERROR&#39;);
    reset_errors();    echo $content;
}

ob_start();echo &#39;Main function...&#39;, PHP_EOL;//搞事情//throw new Exception(&#39;这是一个异常&#39;);trigger_error(&#39;这是一个用户error&#39;);//E_USER_NOTICEif (version_compare(PHP_VERSION, &#39;7.0.0&#39;) >= 0) {
    mcrypt_encrypt();//E_WARNING, E_DEPRECATED} else {
    mysql();
}
unknown_function(); //fatal error$content = ob_get_clean();//优先输出错误print_errors(&#39;MA ERROR&#39;);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!

Stellungnahme:
Dieser Artikel ist reproduziert unter:开发者头条. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen