PHP基础补全系列:异常处理

来源:互联网 发布:休斯顿国际电影节知乎 编辑:程序博客网 时间:2024/05/29 19:30

        异常处理在PHP里也是个很有争议的问题,记得之前做项目的时候,关于异常处理和当时的同事讨论了很久。

        不过今天不讨论这些东西,只是单纯做个记录。

        这篇博客分三个部分:

  1. 异常处理的基本使用
  2. 扩展中抛出的异常,以PDO举例
  3. 将错误信息委托给异常处理
        一些需要注意的tips:
  • 可以使用set_exception_handler自定义异常处理函数(在博客中没写demo)
  • 在PHP7之前的版本中,原生PHP不会抛出异常,异常都需要用户自定义抛出
  • finally关键字在5.5版本由鸟哥加入PHP,之前的版本没有finally
  • 据说在PHP7版本中,大部分的错误处理都会通过异常的方式抛出(时间原因,没有尝试,等以后写错误处理的时候,会将这个补上)
        异常处理的基本使用
        需要注意以下几点:
    • PHP7之前的版本,原生PHP代码不会抛出异常,需要用户自己抛出
    • finally代码块一定会执行
    • 如果catch代码块中处理完异常并返回结果之后,finally代码块会继续执行,并且finally的返回值会覆盖catch代码块的返回值
        具体见代码:
<?phpfunction division ($a, $b) {if(!$b) {throw new Exception("Division by zero");}return $a / $b;}try {$result = division(5, 0);} catch (Exception $e) {echo $e->getMessage();}//结果:异常被捕获,输出"Division by zero"class User_Exception extends Exception {}function user_division ($a, $b) {if(!$b) {throw new User_Exception("User division by zero");}return $a / $b;}try {$result = division(5, 0);} catch (User_Exception $e) {echo $e->getMessage();} catch (Exception $e) {echo $e->getMessage();}//异常被捕获,输出"Division by zero"try {$result = user_division(5, 0);} catch (User_Exception $e) {echo $e->getMessage();} catch (Exception $e) {echo $e->getMessage();}//异常被捕获,输出"User division by zero"try {$result = division(5, 0);} catch (User_Exception $e) {echo $e->getMessage();} catch (Exception $e) {echo $e->getMessage();} finally {echo "finally is excuted";}//异常被捕获,finally代码被执行,输出"Division by zerofinally is excuted";//需要特别之处,finally这个特性是由鸟哥在PHP5.5的版本实现的,见鸟哥的博客http://www.laruence.com/2012/08/16/2709.html//另一个需要注意的地方是,如果在catch代码块中返回了结果,finally还是会继续执行,并且finally的返回值会覆盖catch中的返回值function testFinally () {try {throw new Exception("test Finally");} catch (Exception $e) {echo "catch exception\n";return 0;} finally {echo "finally executed\n";return 1;}}echo testFinally();/** * catch和finally代码块均执行,输出结果为 * catch exception * finally executed * 1 * catch代码块的返回值被finally代码块的返回值覆盖 */

        PDO扩展的demo
    • PDO的连接错误都会默认抛出异常,但是不做设置的话,查询错误会返回false
        具体见代码:
<?phptry {$db = new PDO("mysql:host=127.0.0.1;dbname=test", "root", "");$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);$result = $db->query("SELECT `name` FROM UnknownTable;");} catch (PDOException $e) {echo "Catch exception:" . $e->getMessage();}//异常被捕获,输出"Catch exception:SQLSTATE[HY000] [2002] Connection refused"//这个地方特别有意思,如果不设置错误处理方式,连接错误会默认抛出一个PDO异常,但是查询错误默认会返回false;set_error_handler(function ($error, $errorstr) {echo $errorstr;});try {$db = new PDO("mysql:host=127.0.0.1;dbname=blog", "root", "");$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);$db->query("SELECT * FROM UnknownTable");} catch (PDOException $e) {echo "Catch exception:" . $e->getMessage();}//将错误处理设置为PDO::ERRMODE_WARNING,不会抛出异常,而是提示一个warning信息.//这里特别有意思的地方是,如果我不做处理,命令行里会提示两个报警信息.如果我加入set_error_handler,将错误信息打印出来,则只有一个warning信息.//感觉有时间可以写两篇关于PDO扩展和PHP错误处理的博客


        将错误信息委托给异常处理
    • 其实就是设置自定义错误处理函数,将错误信息构造出一个新的异常抛出
    • 需要特别注意异常的构造,这里写的比较简单
        具体见代码:
<?phpclass Error_Exception extends Exception {function __construct ($message = "", $code = 0, $severity = 1, $filename = __FILE__, $lineno = __LINE__, $previous = NULL) {parent::__construct($message, $code);}}set_error_handler(function ($errno, $errstr, $errfile, $errline) {throw new Error_Exception($errstr, 0, $errno, $errfile, $errline);});try {$result = 5 / 0;} catch (Error_Exception $e) {echo $e->getMessage();}//异常被捕获,输出"Division by zero"


0 0
原创粉丝点击