try catch的详解

分类: 开发语言 > PHP
  1. try{} catch(){}异常处理

    1. try {
           $error = "Always throw this error";
           if ($error)
           {
                throw new Exception($error)
           }
           //不会执行异常后的代码
           echo "Never executed";
      } catch (Exception $e) {
           echo '获取异常信息内容:' . Exception::getMessage() . "\n";
           echo '获取异常链中的前一个异常' . Exception::getPrevious() . "\n";
           echo '获取异常代码' . Exception::getCode() . "\n";
           echo '获取发生异常的程序文件名称' . Exception::getFile() . "\n";
           echo '获取发生异常的代码在文件中的行号' . Exception::getLine() . "\n";
           echo '获取异常追踪信息' . Exception::getTrace() . "\n";
           echo '获取字符串类型的异常追踪信息' . Exception::getTraceAsString() . "\n";
           echo '将异常对象转换为字符串' . Exception::__toString() . "\n";
           echo '异常克隆' . Exception::__clone() . "\n";
      }

    2. 使用异常的函数位于“try”代码块内,如果没有触发异常,则代码将照常继续运行下去,如果异常被触发,会抛出一个异常,并不会执行异常后的代码;“catch”代码块会捕获异常,并创建一个包含异常信息的对象。如果异常没有被捕获,而且又没有使用set_exception_handler()作相应的处理的话,那么将发生一个错误(致命错误),并且输出“Uncaught Exception”(未捕获异常)的错误信息;

  2. try{} catch{}的疑惑并解答:

    1. 问题:如果在try中没有throw抛出异常,是不是catch就捕获不到异常啦?throw不可能莫名其妙抛出异常吧?

      解答:首先,有的异常的是否抛出不是程序员能控制的,比如内存耗尽,所以需要try....catch,另外,有的时候需要通过抛出异常在程序的其他地方进行处理,因为当前上下文缺少处理该异常的信息,所以程序员可以自定义异常,并在某种情况下抛出该异常,外层代码需要try....catch来捕获该异常;

    2. 问题:如果在try中没有throw抛出异常,那么catch会捕获到异常吗?怎么捕获的?如果try中发生异常,那么到底是谁通知catch呢?

      解答:try块里的代码可能没有显示抛出异常,但里面调用的函数有可能抛出异常;怎么捕获的就涉及到异常处理的系统的实现;

    3. 问题:throw到底能干什么呢?

      解答:

      1. 如果try里面调用了某个库函数,那个函数throw了异常,就会在这里被catch。这种情况自己就没法判断,throw产生了一个异常,这个异常会顺着函数调用的级别逐级向上,由最接近的一个catch来处理。如果一直没有catch,又没用使用 set_exception_handler() 作相应的处理的话,那么将发生一个严重的错误(致命错误),并且输出 "Uncaught Exception" (未捕获异常)的错误消息。

      2. 你写的一个方法method()给别人调用,你知道那个方法执行可能会出错,当出错的时候,你需要把错误信息返回给调用者。这时候,你就只能用throw抛出错误。调用者把对method()的调用放在try块里,就能catch到你抛出的错误,从而获得错误信息。

    4. try catch的其他作用:

      1. try的代码段假如没有抛出异常(可能是调用的函数抛出异常),catch确实捕获不到异常;用try catch而不用if能够很快的跳出深层嵌套啊。能够让代码更清晰。

      2. 找到第一个try块,然 后找到对应的catch,假如该异常能被catch处理(类型匹配,其中...处理所有异常),则catch块处理该异常,然后按正常程序继续走下去,回 到正常的函数调用返回链。

      3.  throw的用处是抛出异常,正常的返回用return,而异常用throw。这样程序可以集中处理返回值, 而错误集中在catch块处理,代码逻辑会更清晰明了

  3. PHP异常处理的概念:(http://www.w3school.com.cn/php/php_exception.asp)

    1. 异常(Exception)用于在指定的错误发生时改变脚本的正常流程。

      问题:什么是异常?

      1. PHP 5 提供了一种新的面向对象的错误处理方法。

      2. 异常处理用于在指定的错误(异常)情况发生时改变脚本的正常流程。这种情况称为异常。

      3. 当异常被触发时,通常会发生:

        1. 当前代码状态被保存

        2. 代码执行被切换到预定义的异常处理器函数

        3. 根据情况,处理器也许会从保存的代码状态重新开始执行代码,终止脚本执行,或从代码中另外的位置继续执行脚本

      4. 几种不同的错误处理方法:

        1. 异常的基本使用

          1. 当异常被抛出时,其后的代码不会继续执行,PHP 会尝试查找匹配的 "catch" 代码块。

          2. 如果异常没有被捕获,而且又没用使用 set_exception_handler() 作相应的处理的话,那么将发生一个严重的错误(致命错误),并且输出 "Uncaught Exception" (未捕获异常)的错误消息。

        2. 创建自定义的异常处理器

          1. Try - 使用异常的函数应该位于 "try" 代码块内。如果没有触发异常,则代码将照常继续执行。但是如果异常被触发,会抛出一个异常。

          2. Throw - 这里规定如何触发异常。每一个 "throw" 必须对应至少一个 "catch"

          3. Catch - "catch" 代码块会捕获异常,并创建一个包含异常信息的对象

        3. 创建一个自定义的 Exception 类

          1. 我们简单地创建了一个专门的类,当 PHP 中发生异常时,可调用其函数。该类必须是 exception 类的一个扩展。

          2. 这个自定义的 exception 类继承了 PHP 的 exception 类的所有属性,您可向其添加自定义的函数。

        4. 多个异常

          1. 可以为一段脚本使用多个异常,来检测多种情况。

          2. 可以使用多个 if..else 代码块,或一个 switch 代码块,或者嵌套多个异常。这些异常能够使用不同的 exception 类,并返回不同的错误消息:

        5. 重新抛出异常

          1. 当异常被抛出时,您也许希望以不同于标准的方式对它进行处理。可以在一个 "catch" 代码块中再次抛出异常。

          2. 脚本应该对用户隐藏系统错误。对程序员来说,系统错误也许很重要,但是用户对它们并不感兴趣。为了让用户更容易使用,您可以再次抛出带有对用户比较友好的消息的异常:

        6. 设置顶层异常处理器

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

  4. 案例:

    class a {

         static public function run() {

               throw new Exception( 'a -> run()');    

         }

    }

    class b {

         static public function run() {

               throw new Exception( 'b -> run()');

         }

    }

    $flag = false ;

    try {

         if ($flag) {

              a::run();

              b::run();

         } else {

               throw new Exception( 'c -> run()');

         }

    } catch (Exception $e ) {

         $out = array(0, $e->getCode(), $e->getLine(), $e->getMessage());

         echo json_encode($out);

    }

    exit;

  5. 自定义错误信息:

    error_reporting (0);

    register_shutdown_function($err = 'my_error_handler') OR set_error_handler($err,E_ALL); // 同时注册两个函数.

    // 函数参数错误

    $original  = unserialize ( array (423142 ,2134234 ));

    function my_error_handler($errno = 0, $errstr = 0, $errfile = 0, $errline = 0 ){

         if ($errno && $errfile) {

               if ( true) {

                   $earr = array();

                   $earr[ 'type'] = $errno;

                   $earr[ 'message'] = $errstr;

                   $earr[ 'file'] = $errfile;

                   $earr[ 'line'] = $errline;

              }

         }else {

               $earr = error_get_last();

         }    

         echo '<pre>' ;

         print_r($earr);

         return array();

    }

来源:原创 发布时间:2020-04-26 22:29:32