Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 560|回复: 0

PHP中的错误处理、异常处理机制详解

[复制链接]
  • TA的每日心情
    奋斗
    2024-4-6 11:05
  • 签到天数: 748 天

    [LV.9]以坛为家II

    2034

    主题

    2092

    帖子

    70万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    705612
    发表于 2021-6-30 08:06:45 | 显示全部楼层 |阅读模式

    转自:http://www.cnblogs.com/52php/p/5665495.html

    在编写PHP程序时,错误处理是一个重要的部分。如果程序中缺少错误检测代码,那么看上去很不专业,也为安全风险敞开了大门

    例:

    1
    2
    3
    4
    <?php
         $a  fopen ( 'test.txt' , 'r' );
         //这里并没有对文件进行判断就打开了,如果文件不存在就会报错
    ?>

    那么正确的写法应该如下:

    1
    2
    3
    4
    5
    6
    7
    <?php
         if  ( file_exists ( 'test.txt' )) {
             $f  fopen ( 'test.txt' 'r' );
             // 使用完后关闭
             fclose( $f );
         }
    ?>

    一、PHP错误处理的三种方式

    A、简单的die()语句;

    等价于exit();

    例:

    1
    2
    3
    4
    5
    6
    7
    if  (! file_exists ( 'aa.txt' )) {
         die ( '文件不存在' );
    else  {
         // 执行操作
    }
    // 如果上面die()被触发,那么这里echo接不被执行
    echo  'ok' ;

    简洁写法:

    1
    2
    file_exits( 'aaa.txt' or  die ( '文件不存在' );
    echo  'ok' ;

    B、自定义错误和错误触发器

    1、错误处理器(自定义错误,一般用于语法错误处理)

    创建自定义错误函数(处理器),该函数必须有能力处理至少两个参数(error_level和errormessage),但是可以接受最多五个参数(error_file、error_line、error_context)

    语法:

    function error_function($error_level, $error_message, $error_file, $error_line, $error_context)

    // 创建好后还需要改写set_error_handler();函数

    set_error_handler('error_function', E_WARNING); // 这里error_function对应上面创建的自定义处理器名,第二个参数为使用自定义错误处理器的错误级别;

    错误报告级别(了解即可)

    这些错误报告级别是错误处理程序旨在处理的错误的不同的类型:

    常量 描述
    2 E_WARNING 非致命的 run-time 错误。不暂停脚本执行。
    8 E_NOTICE Run-time 通知。脚本发现可能有错误发生,但也可能在脚本正常运行时发生。
    256 E_USER_ERROR 致命的用户生成的错误。这类似于程序员使用 PHP 函数 trigger_error() 设置的 E_ERROR。
    512 E_USER_WARNING 非致命的用户生成的警告。这类似于程序员使用 PHP 函数 trigger_error() 设置的 E_WARNING。
    1024 E_USER_NOTICE 用户生成的通知。这类似于程序员使用 PHP 函数 trigger_error() 设置的 E_NOTICE。
    4096 E_RECOVERABLE_ERROR 可捕获的致命错误。类似 E_ERROR,但可被用户定义的处理程序捕获。(参见 set_error_handler())
    8191 E_ALL 所有错误和警告,除级别 E_STRICT 以外。(在 PHP 6.0,E_STRICT 是 E_ALL 的一部分)

    2、错误触发器(一般用于处理逻辑上的错误)

    需求:比如要接收一个年龄,如果数字大于120,就认为是一个错误

    传统方法:

    1
    2
    3
    4
    5
    6
    <?php
    if  ( $age  > 120) {
         echo  '年龄错误' ;
         exit ();
    }
    ?>

    使用触发器:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <?php
    if  ( $age  > 120) {
         // trigger_error('错误信息'[,'错误等级']); 这里错误等级为可选项,用于定义该错误的级别
         // 用户定义的级别包含以下三种:E_USER_WARNING 、E_USER_ERROR 、E_USER_NOTICE
         trigger_error( '年龄错误' );  // 这里是调用的系统默认的错误处理方式,我们也可以用自定义处理器
    }
     
    /**
      * 自定义处理器,与上面相同
      */
    function  myerror( $error_level $error_message ) {
         echo  'error text' ;
    }
     
    //  同时需要改变系统默认的处理函数
    set_error_handler( 'myerror' , E_USER_WARNING);  // 同上面,第一个参数为自定义函数的名称,第二个为错误级别【这里的错误级别通常为以下三种:E_USER_WARNING 、E_USER_ERROR 、E_USER_NOTICE】
    // 现在再使用trigger_error就可以使用自定义的错误处理函数了
    ?>

    练习题:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    <?php
    date_default_timezone_set( 'PRC' );
    function  myerror( $error_level $error_message ) {
         $info  "错误号:$error_level" ;
         $info  .=  "错误信息:$error_message" ;
         $info  .=  '发生时间:'  date ( 'Y-m-d H:i:s' );
         $filename  'aa.txt' ;
         if  (! $fp  fopen ( $filename 'a' )) {
             echo  '创建文件'  $filename  '失败' ;
         }
         if  ( is_writeable ( $filename )) {
             if  (!fwrite( $fp $info )) {
                 echo  '写入文件失败' ;
             else  {
                 echo  '已成功记录错误信息' ;
             }
             fclose( $fp );
         else  {
             echo  '文件'  $filename  '不可写' ;
         }
         exit ();
    }
     
    set_error_handler( 'myerror' , E_WARNING);
    $fp  fopen ( 'aaa.txt' 'r' );
    ?>

    C、错误日志

    默认的根据php.ini中error_log配置,PHP向服务器的错误记录系统或文件发送错误记录。通过使用error_log()函数可以向文件或远程目的地发送错误记录;

    语法:

    error_log(error[, type, destination, headers])

    type部分一般用3,表示在文件后面追加错误信息,而不会覆盖原内容destination表示目的地,即存放的文件或远程目的地

    如:error_log("$error_info",3,"errors.txt");

    二、PHP异常处理【重点】

    1、基本语法  

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <?php
    try  {
         // 可能出现错误或异常的代码
         //catch 捕获  Exception是PHP已定义好的异常类
    catch  (Exception  $e ) {
         // 对异常处理,方法:
         //1、自己处理
         //2、不处理,可以再次抛出 throw new Exception('xxx');
    }
    ?>

    2、处理处理程序应当包括:

    1. try - 使用异常的函数应该位于 "try"  代码块内。如果没有触发异常,则代码将照常继续执行。但是如果异常被触发,会抛出一个异常;
    2. throw - 这里规定如何触发异常。每一个 "throw" 必须对应至少一个 "catch";
    3. catch - "catch" 代码块会捕获异常,并创建一个包含异常信息的对象;

    让我们触发一个异常:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    <?php
    /**
      * 创建可抛出一个异常的函数
      */
    function  checkNum( $number ) {
         if  ( $number  > 1) {
             throw  new  Exception( "Value must be 1 or below" );
         }
     
         return  true;
    }
     
    // 在 "try" 代码块中触发异常
    try  {
         checkNum(2);
         // 如果异常被抛出,那么下面一行代码将不会被输出
         echo  'If you see this, the number is 1 or below' ;
    catch  (Exception  $e ) {
         // 捕获异常
         echo  'Message: '  $e ->getMessage();
    }
    ?>
    上面代码将获得类似这样一个错误:
    1
    Message: Value must be 1 or below

    例子解释:

    上面的代码抛出了一个异常,并捕获了它:

    1. 创建 checkNum() 函数,它检测数字是否大于 1,如果是,则抛出一个异常。
    2. 在 "try" 代码块中调用 checkNum() 函数。
    3. checkNum() 函数中的异常被抛出。
    4. "catch" 代码块接收到该异常,并创建一个包含异常信息的对象 ($e)。
    5. 通过从这个 exception 对象调用 $e->getMessage(),输出来自该异常的错误消息。

    不过,为了遵循“每个 throw 必须对应一个 catch”的原则,可以设置一个顶层的异常处理器来处理漏掉的错误。

    set_exception_handler()函数可设置处理所有未捕获异常的用户定义函数。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <?php
    /**
      * 设置一个顶级异常处理器
      */
    function  myexception( $e ) {
         echo  'this is top exception' ;
    }
     
    // 修改默认的异常处理器
    set_exception_handler( "myexception" );
    try  {
         $i  = 5;
         if  ( $i  < 10) {
             throw  new  Exception( '$i must greater than 10' );
         }
    catch  (Exception  $e ) {
         // 处理异常
         echo  $e ->getMessage() .  '<br/>' ;
     
         // 不处理异常,继续抛出
         throw  new  Exception( 'errorinfo' );  // 也可以用throw $e 保留原错误信息;
    }
    ?>

    创建一个自定义的异常类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <?php
    class  customException  extends  Exception {
         public  function  errorMessage() {
             $errorMsg  'Error on line '  $this ->getLine() .  ' in '  $this ->getFile() .  ': <b>'  $this ->getMessage() .  '</b> is not a valid E-Mail address' ;
             return  $errorMsg ;
         }
    }
     
    // 使用
    try  {
         throw  new  customException( 'error message' );
    catch  (customException  $e ) {
         echo  $e ->errorMessage();
    }
    ?>

    可以使用多个catch来返回不同情况下的错误信息

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <?php
    try  {
         $i  = 5;
         if  ( $i  > 0) {
             throw  new  customException( 'error message' );  // 使用自定义异常类处理
         }
         if  ( $i  < -10) {
             throw  new  Exception( 'error2' );  // 使用系统默认异常处理
         }
    catch  (customException  $e ) {
         echo  $e ->getMessage();
    catch  (Exception  $e1 ) {
         echo  $e1 ->getMessage();
    }
    ?>

    异常的规则

    • 需要进行异常处理的代码应该放入 try 代码块内,以便捕获潜在的异常。
    • 每个try或throw代码块必须至少拥有一个对应的 catch 代码块。
    • 使用多个 catch 代码块可以捕获不同种类的异常。
    • 可以在try代码内的catch 代码块中再次抛出(re-thrown)异常。

    简而言之:如果抛出了异常,就必须捕获它。

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-2 09:48 , Processed in 0.076545 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表