Error 层次结构

- Throwable  (php7)
  - Error
     - ArithmeticError
       - DivisionByZeroError
     - AssertionError
     - CompileError
        - ParseError
     - TypeError
        - ArgumentCountError
- Exception
  ...

什么是php错误?

  • 属于php脚本自身的问题,大部分情况是由错误的语法,服务器环境导致,不能再编译期发现运行期的错误,往往导致程序或逻辑无法继续下去而需要中断,甚至无法运行的情况。,如warning、notice都是错误,只是他们的级别不同而已,并且错误是不能被try-catch捕获的。

什么是php的异常?

  • 程序在运行中出现不符合预期的情况,允许发生(你也不想让他出现不正常的情况)但他是一种不正常的情况,按照我们的正常逻辑本不该出的错误,但仍然会出现的错误,属于逻辑和业务流程的错误,而不是编译或者语法上的错误。
  • 程序执行过程中出现意料之外的情况,逻辑上往往是行的通,但不符合应用场景,比如接收到一个长度超出预定格式的用户名。因此,异常主要靠编码人员做预先判断后抛出,捕获异常后改变程序流程来处理这些情况,不必中断程序。

ERROR的级别(而E_ERROR、E_CORE_ERROR、E_COMPILE_ERROR 、E_USER_ERRORE_PARSE产生的错误是直接终止程序的)

error_reporting() 适用版本为PHP 4, PHP 5, PHP 7, PHP 8

  • error_reporting — 设置应该报告何种 PHP 错误
<?php
    // 关闭所有PHP错误报告
    error_reporting(0);
    
    // Report simple running errors
    error_reporting(E_ERROR | E_WARNING | E_PARSE);
    
    // 报告 E_NOTICE也挺好 (报告未初始化的变量
    // 或者捕获变量名的错误拼写)
    error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);
    
    // 除了 E_NOTICE,报告其他所有错误
    error_reporting(E_ALL ^ E_NOTICE);
    
    // 报告所有 PHP 错误 (参见 changelog)
    error_reporting(E_ALL);
    
    // 报告所有 PHP 错误
    error_reporting(-1);
    
    // 和 error_reporting(E_ALL); 一样
    ini_set('error_reporting', E_ALL);
?>
   Fatal Error:致命错误(脚本终止运行)
           E_ERROR         // 致命的运行错误,错误无法恢复,暂停执行脚本
           E_CORE_ERROR    // PHP启动时初始化过程中的致命错误
           E_COMPILE_ERROR // 编译时致命性错,就像由Zend脚本引擎生成了一个E_ERROR
           E_USER_ERROR    // 自定义错误消息。像用PHP函数trigger_error(错误类型设置为:E_USER_ERROR)
   
       Parse Error:编译时解析错误,语法错误(脚本终止运行)
           E_PARSE  //编译时的语法解析错误
   
       Warning Error:警告错误(仅给出提示信息,脚本不终止运行)
           E_WARNING         // 运行时警告 (非致命错误)。
           E_CORE_WARNING    // PHP初始化启动过程中发生的警告 (非致命错误) 。
           E_COMPILE_WARNING // 编译警告
           E_USER_WARNING    // 用户产生的警告信息
   
       Notice Error:通知错误(仅给出通知信息,脚本不终止运行)
           E_NOTICE      // 运行时通知。表示脚本遇到可能会表现为错误的情况.
           E_USER_NOTICE // 用户产生的通知信息。

下面我们主要来说一下处理异常和错误的几个重要的函数

<?php
    /**
     *    errno      第一个参数 errno,包含了错误的级别,是一个 integer。
     *    errstr     第二个参数 errstr,包含了错误的信息,是一个 string。
     *    errfile    第三个参数是可选的,errfile, 包含了发生错误的文件名,是一个 string。
     *    errline    第四个参数是一个可选项, errline, 包含了错误发生的行号,是一个 integer。
     *    errcontext 第五个可选参数, errcontext, 是一个指向错误发生时活动符号表的 array。 也就是说,errcontext 会包含错误触发处作用域内所有变量的数组。 用户的错误处理程序不应该修改错误上下文(context)。
     */
    function myErrorHandler($errno, $errstr, $errfile, $errline)
    {
        if (!(error_reporting() & $errno)) {
            // This error code is not included in error_reporting, so let it fall
            // through to the standard PHP error handler
            return false;
        }
    
        // $errstr may need to be escaped:
        $errstr = htmlspecialchars($errstr);
    
        switch ($errno) {
        case E_USER_ERROR:
            echo "<b>My ERROR</b> [$errno] $errstr<br />\n";
            echo "  Fatal error on line $errline in file $errfile";
            echo ", PHP " . PHP_VERSION . " (" . PHP_OS . ")<br />\n";
            echo "Aborting...<br />\n";
            exit(1);
    
        case E_USER_WARNING:
            echo "<b>My WARNING</b> [$errno] $errstr<br />\n";
            break;
    
        case E_USER_NOTICE:
            echo "<b>My NOTICE</b> [$errno] $errstr<br />\n";
            break;
    
        default:
            echo "Unknown error type: [$errno] $errstr<br />\n";
            break;
        }
    
        /* Don't execute PHP internal error handler */
        return true;
    }
    set_error_handler("myErrorHandler")
?>
<?php
        function shutdown()
        {
            echo 'Script executed with success', PHP_EOL;
        }
        
        register_shutdown_function('shutdown');
?>
?>
<?php
     function exception_handler($exception) {
       echo "Uncaught exception: " , $exception->getMessage(), "\n";
     }
     
     set_exception_handler('exception_handler');
     
     throw new Exception('Uncaught Exception');
     echo "Not Executed\n";
 ?>

PHP7中的异常处理(原来老的Exception和其中一部分Error实现了这个接口Throwable)

<?php
  try {
        //throw new \Error('模拟错误代码');
        //throw new \Exception('模拟异常代码');
    }catch (\Throwable $throwable) {
       echo  $throwable->getMessage();    
    }
    try {
        //throw new \Error('模拟错误代码');
        //throw new \Exception('模拟异常代码');
    }catch (\Error $error) {
        $error->getMessage(); 
    }
?>
Last modification:February 1, 2021
如果觉得我的文章对你有用,请随意赞赏