• PHP10 错误和异常处理


    学习要点

    • 修改错误报告级别
    • 写错误日志
    • 异常处理实现
    • 自定义异常
    • 捕获多路异常

     

    错误处理

    定义

    • 错误:开发过程中的失误、用户操作引起的错误。
    • 错误产生原因
    1. 语法错误:开发环境提示,未修正则脚本无法运行。
    2. 运行时错误:脚本无法正确运行。例如双引号字符串对变量的解析。
    3. 逻辑错误:常见的逻辑运算错误,循环条件设置错误等等。

    错误报告级别

    1、WAMP作为开发环境,在php.ini配置文件中,有两个参数设置:

    • display_errors = on

        注释:PHP解析器将会输出错误报告的功能。如果是产品正式发布部署,需要在PHP服务器上把此项值值为off。

    • error_reporting = E_ALL

        注释:PHP解析器将输出每个错误。

    2、PHP的错误报告级别:

    常量

    描述

    1

    E_ERROR

    Fatal run-time errors. Errors that can not be recovered from. Execution of the script is halted

    2

    E_WARNING

    Non-fatal run-time errors. Execution of the script is not halted

    4

    E_PARSE

    Compile-time parse errors. Parse errors should only be generated by the parser

    8

    E_NOTICE

    Run-time notices. The script found something that might be an error, but could also happen when running a script normally

    16

    E_CORE_ERROR

    Fatal errors at PHP startup. This is like an E_ERROR in the PHP core

    32

    E_CORE_WARNING

    Non-fatal errors at PHP startup. This is like an E_WARNING in the PHP core

    64

    E_COMPILE_ERROR

    Fatal compile-time errors. This is like an E_ERROR generated by the Zend Scripting Engine

    128

    E_COMPILE_WARNING

    Non-fatal compile-time errors. This is like an E_WARNING generated by the Zend Scripting Engine

    256

    E_USER_ERROR

    Fatal user-generated error. This is like an E_ERROR set by the programmer using the PHP function trigger_error()

    512

    E_USER_WARNING

    Non-fatal user-generated warning. This is like an E_WARNING set by the programmer using the PHP function trigger_error()

    1024

    E_USER_NOTICE

    User-generated notice. This is like an E_NOTICE set by the programmer using the PHP function trigger_error()

    2048

    E_STRICT

    Run-time notices. PHP suggest changes to your code to help interoperability and compatibility of the code

    4096

    E_RECOVERABLE_ERROR

    Catchable fatal error. This is like an E_ERROR but can be caught by a user defined handle (see also set_error_handler())

    8191

    E_ALL

    All errors and warnings, except level E_STRICT (E_STRICT will be part of E_ALL as of PHP 6.0)

    3、开启错误报告

    处理在php.ini文件中配置,如果对服务器权限不够,可以采用ini_set()函数设置:

    例如:

    ini_set(‘display_errors’,1);
    

      

    调整错误报告级别

    1、在php.ini中修改配置指令error_reporting的值

    默认值:

    error_reporting = E_ALL

    修改示例1(结合位运算符&,|,~):除运行时注意消息外的全部错误报告

    error_reporting = E_ALL&~E-NOTICE; 

    修改示例2:只考虑运行时错误、解析错误、核心错误

    error_reporting = E_ERROR | E_PARSE | E_CORE_ERROR
    

       

    2、在脚本中使用error_reporting()函数

      权限不够,或者需要个性化页面错误报告,采用该函数。

    error_reporting(0);     //完全关闭错误报告
    
    error_reporting(E_ALL);    //报告任何错误
    
    error_reporting(E_ALL&~E_NOTICE);    //报告除注意外的任何错误
    

      

    示例:

    /* 开启php.ini中的display_errors指令*/
    
           ini_set ( 'display_errors', 1);
    
           /* 通过error_reporting()函数设置在本脚本中,输出所有级别的错误报告 */
    
           error_reporting ( E_ALL );
    
    //error_reporting ( E_ALL &~(E_WARNING|E_NOTICE));     
    
           /* “注意(notice)”的报告,不会阻止脚本的执行,并且可能不一定是一个问题 */
    
           getType ( $var ); // 调用函数时提供的参数变量没有在之前声明    
    
           /* “警告(warning)”的报告,指示一个问题,但是不会阻止脚本的执行 */
    
           getType (); // 调用函数时没有提供必要的参数     
    
           /* “错误(error)”的报告,它会终止程序,脚本不会再向下执行 */
    
        get_Type (); // 调用一个没有被定义的函数    
    

      

    使用trigger_error()函数代替die()函数

    die()等同于exit(),会退出程序。而trigger_error()可以生成一个用户警告来代替退出程序。

    示例代码:

    //die("程序运行结束!");
    
    trigger_error("there is a bugbugbug!",E_USER_WARNING);
    
    echo "这里是php文件尾巴";
    

      

    自定义错误处理

    1、需要自定义错误信息的情形

      • 记录错误信息
      • 屏蔽错误信息
      • 错误统一输出页面处理或者同一页面位置输出错误信息
      • 调试

    2、如何自定义错误处理

    用户自定义错误处理函数:set_error_handler()

    语法格式:

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

      

    参数说明:

    error_handler:

    handler ( int $errno , string $errstr [, string $errfile [, int $errline [, array $errcontext ]]] )  //四个参数含义:错误级别、错误信息、错误所在文件,错误所在文件第几行

    error_types:

    错误报告级别。默认E_ALL。

    示例代码:

    // 屏蔽所有错误报告
    
    error_reporting ( 0 );
    
    function error_handler($error_level, $error_message, $file, $line) {
    
       $EXIT = false;
    
       $error_type='';
    
       switch ($error_level) {
    
          //提醒
    
          case E_NOTICE :
    
          case E_USER_NOTICE :
    
             $error_type = 'Notice';
    
             break;
    
          //警告
    
          case E_WARNING :
    
          case E_USER_WARNING :
    
             $error_type = 'Warning';
    
             break;
    
          //错误
    
          case E_ERROR :
    
          case E_USER_ERROR :
    
             $error_type = 'Fatal Error';
    
             break;
    
          //未知错误
    
          default:
    
             $error_type = 'Unknown';
    
             $EXIT=true;
    
             break;
    
       }
    
      
    
       //打印错误信息,可以自定义错误格式
    
       printf("%s,%s,%s,%d",$error_type,$error_message,$file,$line);
    
       if(true==$EXIT){
    
          echo '<script>location="error.php";</script>';
    
       }
    
    }
    
     
    
    set_error_handler('error_handler');
    
    //echo $novar;
    
    echo 3/0;
    

      

    注意:

    1、set_error_handler()不处理以下错误报告:E_ERR0R、E_PARSE、E_CORE_ERROR、E_CORE_WARNING、E_COMPILE_ERROR、E_COMPILE_WARNING。不处理不等于不显示错误信息,它不会按照用户设定格式显示。

    2、除了第1条中列出的错误,在使用了set_error_handler()函数后,所有的错误都交给用户处理。

    上机练习1:自定义错误处理

    1、  set_error_handler()函数的用法

    2、  自定义回调函数

    3、  错误报告格式:

    写错误日志

    PHP项目部署运行后,一般display_errors = off。程序日常运行的错误信息是需要记录下来,作为运维参考,如何处理?有两种记录日志的方式:

    1、使用指定的文件记录错误报告日志

    php.ini配置

    error_reporting = E_ALL

    display_errors = off

    log_errors=on

    log_errors_max_len = 1024

    error_log = "d:/wamp/logs/php_error.log"

    error_log()函数

    //写入操作系统日志 (需要php.ini中设置error_log=syslog)
    
    error_log("error message",0);
    
    //发送到电子邮件(需要邮件服务器)
    
    error_log("error message",1,"2083967667@qq.com");
    
    //发送到某个ip的某个端口
    
    error_log("error message",2,"localhost:5000");
    
    //写入到某个路径文件中
    
    error_log("error message",3,"er.log");
    

      

    2、错误信息记录到操作系统日志中

    php.ini配置

    error_reporting = E_ALL

    display_errors = off

    log_errors=on

    log_errors_max_len = 1024

    error_log = syslog

    使用syslog向系统发送订制消息

    //php5.3开始,已经废除相关函数
    
    define_syslog_variables();
    
    ……
    

      

    异常处理

    定义

    Exception:在程序执行过程中出现的一个例外或是一个事件,它中断了正常指令的运行,跳转到其他程序模块继续执行。

    简单异常处理

    1、语法结构

    try{
    
    //需要捕获异常的代码块
    
    }catch (Exception $ex1){
    
    //处理异常
    
    } finally {
    
    //始终被执行的代码
    
    }
    

      

    2、示例代码

     

    try {
    
       $number = 100;
    
       $div = 0;
    
       if ($div == 0) {
    
          throw new Exception ( "除数不能为0" );
    
       }
    
       $result=$number/$div;
    
       echo '计算结果'.$result;
    
    } catch ( Exception $e ) {
    
       echo '程序异常:'.$e->getMessage();
    
    }finally {
    
       echo '<br>finally代码始终执行';
    
    }
    
    echo '<br>程序继续执行';
    

      

    自定义异常处理类

    1、内置Exception类结构

    class Exception {
    
     
    
       protected $message = 'Unknown exception'; // 异常信息
    
       protected $code = 0; // 用户自定义异常代码
    
       protected $file; // 发生异常的文件名
    
       protected $line; // 发生异常的代码行号
    
     
    
       function __construct($message = null, $code = 0);
    
     
    
       final function getMessage(); // 返回异常信息
    
       final function getCode(); // 返回异常代码
    
       final function getFile(); // 返回发生异常的文件名
    
       final function getLine(); // 返回发生异常的代码行号
    
       final function getTrace(); // backtrace() 数组
    
       final function getTraceAsString(); // 已格成化成字符串的 getTrace() 信息
    
       /* 可重载的方法 */
    
       function __toString(); // 可输出的字符串
    
    }
    

      

    2、自定义异常处理类

    /* 自定义异常处理类 */
    
    class MyException extends Exception {
    
       // 重写构造函数
    
       public function __construct($message, $code = 0) {
    
          parent::__construct ( $message, $code );
    
       }
    
      
    
       /*重写父类__toString魔术方法*/
    
       public function __toString() {
    
          return __CLASS__ . ":[" . $this->code . "]:" . $this->message . "<br>";
    
       }
    
      
    
       /*自定义异常方法*/
    
       public function customFunction() {
    
          echo "按自定义的方法处理出现的这个类型的异常<br>";
    
       }
    
    }
    
     
    
    try {
    
       $error = '允许抛出这个错误';
    
       throw new MyException ( $error );
    
       echo '出现异常,不被执行的代码.....';
    
    } catch ( MyException $e ) {
    
       echo '捕获异常: ' . $e;
    
       $e->customFunction ();
    
    }
    
    echo '程序继续执行......';
    

      

    上机练习2:自定义异常处理

    多路异常捕获

    class MyException extends Exception {
    
       public function __construct($message, $code = 0) {
    
          parent::__construct ( $message, $code );
    
       }
    
       public function __toString() {
    
          return __CLASS__ . ":[" . $this->code . "]:" . $this->message . "<br>";
    
       }
    
       public function customFunction() {
    
          echo "按自定义的方法处理出现的这个类型的异常";
    
       }
    
    }
    
     
    
    class TestException {
    
       public $var;
    
       function __construct($value = 0) {
    
          switch ($value) {
    
             case 1 :
    
                throw new MyException ( "传入的值“1” 是一个无效的参数", 5 );
    
                break;
    
             case 2 :
    
                throw new Exception ( "传入的值“2”不允许作为一个参数", 6 );
    
                break;
    
             default :
    
                $this->var = $value;
    
                break;
    
          }
    
       }
    
    }
    
    // 示例1,在没有异常时,程序正常执行,try中的代码全部执行并不会执行任何catch区块
    
    $testObj=null;
    
    try {
    
       $testObj = new TestException (); // 使用默认参数创建异常的测试类对象
    
       echo "***********<br>"; // 没有抛出异常这条语句就会正常执行
    
    } catch ( MyException $e ) { // 捕获用户自定义的异常区块
    
       echo "捕获自定义的异常:$e <br>"; // 按自定义的方式输出异常消息
    
       $e->customFunction (); // 可以调用自定义的异常处理方法
    
    } catch ( Exception $e ) { // 捕获PHP内置的异常处理类的对象
    
       echo "捕获默认的异常:" . $e->getMessage () . "<br>"; // 输出异常消息
    
    }
    
    var_dump ( $testObj ); // 判断对象是否创建成功,如果没有任何异常,则创建成功
    
                       
    
    // 示例2,抛出自定义的异常,并通过自定义的异常处理类捕获这个异常并处理
    
    $testObj1=null;
    
    try {
    
       $testObj1 = new TestException ( 1 ); // 传入参数1时,创建测试类对象抛出自定义异常
    
       echo "***********<br>"; // 这个语句不会被执行
    
    } catch ( MyException $e ) { // 这个catch区块中的代码将被执行
    
       echo "捕获自定义的异常:$e <br>";
    
       $e->customFunction ();
    
    } catch ( Exception $e ) { // 这个catch区块不会执行
    
       echo "捕获默认的异常:" . $e->getMessage () . "<br>";
    
    }
    
    var_dump ( $testObj1 ); // 有异常产生,这个对象没有创建成功
    
                        
    
    //示例2,抛出内置的异常,并通过自定义的异常处理类捕获这个异常并处理
    
    $testObj2=null;
    
    try {
    
       $testObj2 = new TestException ( 2 ); // 传入参数2时,创建测试类对象抛出内置异常
    
       echo "***********<br>"; // 这个语句不会被执行
    
    } catch ( MyException $e ) { // 这个catch区块不会执行
    
       echo "捕获自定义的异常:$e <br>";
    
       $e->customFunction ();
    
    } catch ( Exception $e ) { // 这个catch区块中的代码将被执行
    
       echo "捕获默认的异常:" . $e->getMessage () . "<br>";
    
    }
    
    var_dump ( $testObj2 ); // 有异常产生,这个对象没有创建成功
    

      



    本博客文章未经许可,禁止转载和商业用途!

    如有疑问,请联系: 2083967667@qq.com


  • 相关阅读:
    Day12:前端代码的合并和登录过程的完善
    Day11:基本界面的完成
    Day10:界面的跳转
    Day9:尝试连接绑定数据与API
    Day8:转战前端开发
    Day7:熟悉搭建服务器工具及配置
    Day6:完成API的列举设计
    day14
    day13
    day13
  • 原文地址:https://www.cnblogs.com/rask/p/9016333.html
Copyright © 2020-2023  润新知