Home  >  Article  >  Backend Development  >  Details and examples of Exception and Error Handler in PHP

Details and examples of Exception and Error Handler in PHP

王林
王林forward
2019-08-20 09:58:223119browse

Preface

There is a function that needs to be implemented in the recent project: in debugging mode, all errors are output in advance, and then the page content is output.

In order to realize the above function , you need to use Exception, Error related Handler methods, and found many pitfalls, so I wrote this article to share with you.

Recommended PHP video tutorial: https://www.php.cn/course/ list/29/type/2.html

##Main functions

This article focuses on the following functions

1,

error_reporting()

2、

set_error_handler()

3、

set_exception_handler()

4、

register_shutdown_function()

5,

error_get_last()

The following article focuses on the list of issues:

1,

error_reporting() What is the connection with error_get_last() ?

2,

set_error_handler() is bound to set_exception_handler() When will handler be started? How are they related?

3. Is

register_shutdown_function() usually related to Exception/Error ?

Question solving:

1. What is the connection between

error_reporting() and error_get_last()?

link:

php.net - error_reporting()link: <br>php.net - error_get_last()

a:

int error_reporting ([ int $level ] )

Everyone should be familiar with it, so I won’t go into details.

b:

array error_get_last (void)

Get the last error that occurred

Usually used to get the Fatal Error during PHP running (PHP 5).

The two functions are not closely related literally, but please Observe the following code and output

<?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()Although it explains how to get the last error, it is actually the same. But it does not explain it and is error_reporting() Is it possible for ignored errors to be obtained? Therefore, when we use error_get_last(), we need to pay attention to the errors that are usually ignored, such as: E_DEPRECATED

2 .

set_error_handler() When will the handler bound to set_exception_handler() be started? What is their connection?

link:

php.net - set_error_handler()link: <br>php.net - set_exception_handler()

a、

mixed set_error_handler (callable $error_handler [, int $error_types = E_ALL | E_STRICT ] )

Set user-defined error handling function

<br>

Usually triggered when some non-interruptive errors occur during the running of PHP scripts .

We will use this to record error logs or direct output and other operations.<br>

Note:

FALSE: Standard error handling will still be performed (standard Error handling determines whether to output to

stderr)1 based on display_errors = true/false

. The parameter

$error_types is mostly set to error_reporting(), but it is recommended to set it to E_ALL. It is obviously more flexible to judge which errors need to be processed and which ones do not need to be processed in the handler.

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>

The above is the detailed content of Details and examples of Exception and Error Handler in PHP. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:开发者头条. If there is any infringement, please contact admin@php.cn delete