PHP 错误和异常处理

[TOC]

错误和异常介绍

  • Error一般是系统报的(或者通过trigger_error手动抛出错误),Exception一般是用户Throw抛出的【一般需要自定义set_exception_handler、set_error_handler来处理异常和错误。如果没有处理,配置了记录日志,错误会写到php_errors.log中】

  • Error类和Exception类都是Throwable的子类(实际上是Error类和Exception类都实现了Throwable接口)

  • 【php5】Error 类并非继承自 Exception 类,所以不能用 catch (Exception $e) { ... } 来捕获 Error

  • 【PHP7】改变了大多数错误的报告方式。不同于传统(PHP5)的错误报告机制,现在大多数错误被作为 Error 异常抛出。这种 Error 异常可以像 Exception 异常一样被第一个匹配的 try / catch 块所捕获

  • 如果没有匹配的 catch 块,则调用异常处理函数(事先通过 set_exception_handler() 注册)进行处理。

  • 如果尚未注册异常处理函数,则按照传统方式处理:被报告为一个致命错误(Fatal Error)。可以利用register_shutdown_function()函数来捕获致命错误。

  • 你可以用 catch (Error $e) { ... },或者通过注册异常处理函数( set_exception_handler())来捕获 Error。

同时捕获 Exception异常和Error异常

多次运行可以看到,不管是Exception异常还是Error异常,都可以被捕获处理了。
如果不想所有的错误都用 try / catch 处理,还可以使用set_exception_handler注册异常处理函数,这样当有未被catch的异常产生时,系统会为我们自动调用注册的处理函数来处理。

function _error_handler($errno, $errstr, $errfile, $errline) {
    echo "错误编号errno: $errno
"; echo "错误信息errstr: $errstr
"; echo "出错文件errfile: $errfile
"; echo "出错行号errline: $errline
"; } set_error_handler('_error_handler', E_ALL | E_STRICT); // 注册错误处理方法来处理所有错误 try { echo $foo['bar']; // 由于数组未定义,会产生一个notice级别的错误 trigger_error('人为触发一个错误', E_USER_ERROR); //人为触发错误 if (mt_rand(1, 10) > 5) { throw new Exception('This is a exception', 400); //抛出一个Exception,看是否可以被catch } else { foobar(3, 5); //调用未定义的方法将会产生一个Error级别的错误 } } catch (Throwable $e) { echo "Error code: " . $e->getCode() . '
'; echo "Error message: " . $e->getMessage() . '
'; echo "Error file: " . $e->getFile() . '
'; echo "Error fileline: " . $e->getLine() . '
'; }

php错误异常处理函数

register_shutdown_function('Think\Think::fatalError');   #致命错误时 或者异常终止时
set_error_handler('Think\Think::appError');函数设置用户自定义的错误处理函数。
set_exception_handler('Think\Think::appException'); 函数设置用户自定义的异常处理函数。
error_get_last() 函数获取最后发生的错误。
trigger_error() #函数创建用户定义的错误消息。

set_exception_handler 异常处理

自定义的异常处理函数。

set_exception_handler() 函数设置用户自定义的异常处理函数。
该函数用于创建运行时期间的用户自己的异常处理方法。
该函数会返回旧的异常处理程序,若失败,则返回 null。
function myException($exception){
    echo "Exception: " , $exception->getMessage();
}
set_exception_handler('myException'); //('Think\Think::appException');
throw new Exception('Uncaught Exception occurred'); 

set_error_handler 错误处理

自定义错误处理函数。

function customError($errno, $errstr, $errfile, $errline) {
    echo "Custom error: [$errno] $errstr
"; echo " Error on line $errline in $errfile
"; echo "Ending Script"; die(); } //set error handler set_error_handler("customError"); #set_error_handler('Think\Think::appError'); $test = 2; //trigger error if ($test > 1) { trigger_error("A custom error has been triggered"); }

register_shutdown_function('Think\Think::fatalError');

致命错误时 或者异常终止时调用的函数

    执行机制是:PHP把要调用的函数调入内存。当页面所有PHP语句都执行完成时,再调用此 函数。注意,在这个时候从内存中调用,不是从PHP页面中调用,所以上面的例子不能使用相对路径,因为PHP已经当原来的页面不存在了。就没有什么相对路 径可言。是指在执行完所有PHP语句后再调用函数,不要理解成客户端关闭流浏览器页面时调用函数。
    可以这样理解调用条件:
    1、当页面被用户强制停止时
    2、当程序代码运行超时时
    3、当PHP代码执行完成时
    4,致命错误时
    调用:
        1、 register_shutdown_function(array(&$this, 'close_session')); 
            当前对象的引用:&$this,  回调函数:当前对象的方法。
        2、 register_shutdown_function(“callback”);
            回调函数:callback。
    
    $clean  =  false ;
    function  shutdown_func (){
        global  $clean ;
        if (! $clean ){
            die( 'not a clean shutdown' );
        }
        return  false ;
    }

    register_shutdown_function ('shutdown_func');

    $a  =  1 ;
    $a  = new  FooClass ();  // 将因为致命错误而失败
    $clean  =  true ;

    #执行结果
    //Fatal error: Class 'FooClass' not found in D:\xampp\htdocs\qiqi\aaa.php on line 37
    //not a clean shutdown

trigger_error()

用系统内置函数输出错误

trigger_error() 用于在用户指定的条件下触发一个错误消息。它与内建的错误处理器一同使用,
也可以与由 set_error_handler() 函数创建的用户自定义函数使用。
如果指定了一个不合法的错误类型,该函数返回 false,否则返回 true。

$test=2;
if ($test>1){
    trigger_error("A custom error has been triggered");
}

Notice: A custom error has been triggered
in C:\webfolder\test.php on line 6

debug_backtrace

产生一条回溯跟踪
debug_print_backtrace() - 打印一条回溯

debug_backtrace() - show all options 打印结果最复杂也最全面
debug_backtrace(1) - same as debug_backtrace() 打印结果最复杂也最全面
debug_backtrace(0) - exlude ["object"] 中间
debug_backtrace(2) - exlude ["object"] AND ["args"] 打印结果最简洁

// filename: /tmp/a.php
function a_test($str){
    echo "\nHi: $str";
    var_dump(debug_backtrace());
}
a_test('friend');

// filename: /tmp/b.php
include_once '/tmp/a.php';


Hi: friend
array(2) {
[0]=>
array(4) {
    ["file"] => string(10) "/tmp/a.php"
    ["line"] => int(10)
    ["function"] => string(6) "a_test"
    ["args"]=>
    array(1) {
      [0] => &string(6) "friend"
    }
}
[1]=>
array(4) {
    ["file"] => string(10) "/tmp/b.php"
    ["line"] => int(2)
    ["args"] =>
    array(1) {
      [0] => string(10) "/tmp/a.php"
    }
    ["function"] => string(12) "include_once"
  }
}

error_get_last()

获取最后发生的错误。

error_get_last() 函数获取最后发生的错误。
该函数以数组的形式返回最后发生的错误。
返回的数组包含 4 个键和值:
[type] - 错误类型
[message] - 错误消息
[file] - 发生错误所在的文件
[line] - 发生错误所在的行

你可能感兴趣的:(PHP 错误和异常处理)