• PHP的异常处理、错误的抛出及错误回调函数


    一、错误、异常和等级常量表

    error:不能再编译期发现运行期的错误,不如试图echo输出一个未赋值的变量,这类问题往往导致程序或逻辑无法继续下去而需要中断。

    exception:程序执行过程中出现意料之外的情况,逻辑上往往是行的通,但不符合应用场景,比如接收到一个长度超出预定格式的用户名。因此,异常主要靠编码人员做预先判断后抛出,捕获异常后改变程序流程来处理这些情况,不必中断程序。

    PHP对于异常和错误的界定似乎不是很明显,尤其是低版本的php。

    错误和日志记录

    常量

    说明

    备注

    1

    E_ERROR (integer)

    致命的运行时错误。这类错误一般是不可恢复的情况,例如内存分配导致的问题。后果是导致脚本终止不再继续运行。

     

    2

    E_WARNING (integer)

    运行时警告 (非致命错误)。仅给出提示信息,但是脚本不会终止运行。

     

    4

    E_PARSE (integer)

    编译时语法解析错误。解析错误仅仅由分析器产生。

     

    8

    E_NOTICE (integer)

    运行时通知。表示脚本遇到可能会表现为错误的情况,但是在可以正常运行的脚本里面也可能会有类似的通知。

     

    16

    E_CORE_ERROR(integer)

    在PHP初始化启动过程中发生的致命错误。该错误类似E_ERROR,但是是由PHP引擎核心产生的。

    since PHP 4

    32

    E_CORE_WARNING(integer)

    PHP初始化启动过程中发生的警告 (非致命错误) 。类似E_WARNING,但是是由PHP引擎核心产生的。

    since PHP 4

    64

    E_COMPILE_ERROR(integer)

    致命编译时错误。类似E_ERROR, 但是是由Zend脚本引擎产生的。

    since PHP 4

    128

    E_COMPILE_WARNING(integer)

    编译时警告 (非致命错误)。类似 E_WARNING,但是是由Zend脚本引擎产生的。

    since PHP 4

    256

    E_USER_ERROR(integer)

    用户产生的错误信息。类似 E_ERROR, 但是是由用户自己在代码中使用PHP函数 trigger_error()来产生的。

    since PHP 4

    512

    E_USER_WARNING(integer)

    用户产生的警告信息。类似 E_WARNING, 但是是由用户自己在代码中使用PHP函数 trigger_error()来产生的。

    since PHP 4

    1024

    E_USER_NOTICE(integer)

    用户产生的通知信息。类似 E_NOTICE, 但是是由用户自己在代码中使用PHP函数 trigger_error()来产生的。

    since PHP 4

    2048

    E_STRICT (integer)

    启用 PHP 对代码的修改建议,以确保代码具有最佳的互操作性和向前兼容性。

    since PHP 5

    4096

    E_RECOVERABLE_ERROR(integer)

    可被捕捉的致命错误。 它表示发生了一个可能非常危险的错误,但是还没有导致PHP引擎处于不稳定的状态。 如果该错误没有被用户自定义句柄捕获 (参见 set_error_handler()),将成为一个E_ERROR 从而脚本会终止运行。

    since PHP 5.2.0

    8192

    E_DEPRECATED(integer)

    运行时通知。启用后将会对在未来版本中可能无法正常工作的代码给出警告。

    since PHP 5.3.0

    16384

    E_USER_DEPRECATED(integer)

    用户产少的警告信息。 类似 E_DEPRECATED, 但是是由用户自己在代码中使用PHP函数 trigger_error()来产生的。

    since PHP 5.3.0

    30719

    E_ALL (integer)

    E_STRICT出外的所有错误和警告信息。

    30719 in PHP 5.3.x, 6143 in PHP 5.2.x, 2047 previously

    二、error_reporting()以及try-catch、throw

    error_reporting()函数可以获取(不传参数时)、设定脚本处理哪些异常(并非所有异常都需要处理,例如E_CORE_WARNING、E_NOTICE、E_DEPRECATED是可以忽略的),该设定将覆盖php.ini中的error_reporting选项定义的异常处理设定。

    例如:error_reporting(E_ALL&~E_NOTICE);//除了E_NOTICE其他异常都会触发

    try-catch 无法在类的自动加载函数__autoload()内生效。

    Try-catch 用于捕获异常,无法捕获错误,例如:trigger_error()触发的错误,异常和错误是不一样的。

    Exception类的结构:其中大部分方法都是禁止改用的(final)

    class Exception  {
    protected $message;
    private $string;
    protected $code;
    protected $file;
    protected $line;
    private $trace;
     
     
    final private function __clone () {}
     
    /**
     * @param message[optional]
     * @param code[optional]
     
    */
    public function __construct ($message$code) {}
     
    final public function getMessage () {}
     
    final public function getCode () {}
     
    final public function getFile () {}
     
    final public function getLine () {}
     
    final public function getTrace () {}
     
    final public function getTraceAsString () {}
     
    public function __toString () {}
     
    }


    Try-catch可以有多个catch子句,从第一个catch子句开始,如果子句内的异常变量类型匹配throw语句抛出的异常类型,则该子句会被执行而不再执行其他catch子句,否则继续尝试下一个catch子句。由于Exception是所有异常类的基类,因此抛出的异常都会与它匹配,如果需要根据不同异常类型使用不同的处理方法,应该讲Exception类型的catch子句放到最后。

    Exception是所有异常的基类,可以根据实际需要扩展异常类。

    <?php
    header("content-type:text/html;charset='utf-8'");
    class MyException extends Exception{
    public $errType = 'default';
    public function __construct($errType){
    $this->errType = $errType;
    }
    }
    try{
    // you codes that maybe cause an error
    if(isset($a)){
    echo $a;
    }else{
    throw new Exception("变量未设置!");
    }
    }catch(MyException $err){
    echo $err->errType;
    }catch(ErrorException $err){
    echo "error!";//ErrorException 是 PHP 5 增加的异常类以便将错误封装为异常,可以更好地处理错误信息,继承于 Exception
    }catch(Exception $err){
    echo $err->getMessage();
    }
    ?>

    三、Exception异常回调函数

    <?php
    set_exception_handler('exceptionHandlerFun');//发生exception或其子类的异常时会调此函数
     
    function exceptionHandlerFun($errObj){//exception异常的回调函数只有一个参数,就是抛出的异常对象
    //.........

    }
    ?>
    <?php
    function exception_handler($exception) {
      echo "Uncaught exception: " , $exception->getMessage(), " ";
    }
     
    set_exception_handler('exception_handler');
     
    throw new Exception('Uncaught Exception');
    echo "Not Executed ";
    ?> 

    Exception异常的回调函数并不能像set_error_handler的回调函数那样通过返回true来使异常被清除,即使回调函数处理了异常,后继代码也不会被继续执行,因此想继续执行后续代码必须使用try-catch,try-catch内被捕获的异常不会触发exception_handler。

    四、trigger_error(string errorMsg,int user_error_type)

    该函数用于主动触发一个错误:user_error_type只能是E_ALL、E_USER_ERROR、E_USER_WARNING、E_USER_NOTICE或其组合值。

    注册error(包括系统抛出的error和用户抛出的error)的处理函数和清除error:

    set_error_handler(callback functionName[ ,user_error_type]);//为trigger_error()设置一个回调函数来处理错误,包括系统抛出的错误和用户使用trigger_error()函数触发的错误。

    可选参数user_error_type:

    如果设定次参数,则trigger_error抛出的错误类型符合在user_error_type的定义范围才能触发回调函数。

    第一个参数(callback functionName):

    一个函数名,该函数可以有5个参数,其中前2个必选,依次是:

    Trigger_error抛出的user_error_type、trigger_error抛出的errorMsg、抛出错误的文件绝对路径、抛出错误的行号、抛出错误时的上下文环境。

    回调函数的返回值:如果返回false,系统错误处理机制仍然继续抛出该错误,返回true或无返回值则消除错误。


  • 相关阅读:
    TongWEB与JOnAS 对比,国产中间件战斗机东方通TongWEB源码解析
    矢量图查找 阿里巴巴(矢量图标)
    中兴 F412 超级帐号telecomadmin破解(适用2015版h啊RowCount="0") TEWA-300AI EPON TEWA-500AI EPON破解
    swing版网络爬虫-丑牛迷你采集器2.0
    jeecms 单页静态化方法
    panabit允许一台代理服务器只能收QQ企业邮箱,和内网ip通讯,限制除了QQ企业邮箱以外的所有内容规则
    LNMP安装快速导航(Linux一键安装php环境)
    射手网推荐的书
    [原创]JEECMS 自定义标签调用广告版位下的所有广告(利用广告管理管理首页幻灯片)
    jeecms一些经典标签
  • 原文地址:https://www.cnblogs.com/zhouguowei/p/5208979.html
Copyright © 2020-2023  润新知