在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
一、总结一句话总结:throwable接口+Error类在PHP7更新中有一条:更多的Error变为可捕获的Exception,现在的PHP7实现了一个全局的throwable接口,原来老的Exception和其中一部分Error实现了这个接口(interface),PHP7中更多的Error变为可捕获的Exception返回给捕捉器,这样其实和前面提到的扩展try-catch影响范围一样,但是如果不捕获则还是按照Error对待
1、PHP7中更多的Error变为可捕获的Exception的代码表现是什么?从catch(Exception $e)到catch(Throwable $e)和catch(Error $e)<?php try { test(); } catch(Throwable $e) { echo $e->getMessage() . ' zyf'; } try { test(); } catch(Error $e) { echo $e->getMessage() . ' zyf'; } ?>
2、PHP中什么是异常?逻辑和业务流程的错误,而不是编译或者语法上的错误程序在运行中出现不符合预期的情况,允许发生(你也不想让他出现不正常的情况)但他是一种不正常的情况,按照我们的正常逻辑本不该出的错误,但仍然会出现的错误,属于逻辑和业务流程的错误,而不是编译或者语法上的错误。
3、PHP中什么是错误?错误的语法,服务器环境导致等等属于php脚本自身的问题,大部分情况是由错误的语法,服务器环境导致,使得编译器无法通过检查,甚至无法运行的情况。warning、notice都是错误,只是他们的级别不同而已,并且错误是不能被try-catch捕获的。
4、不同语言中的错误和异常是一样的么?不一样,比如java中的异常指 和预期不一致异常和错误的说法在不同的语言有不同的说法。在PHP中任何自身的错误或者是非正常的代码都会当做错误对待,并不会以异常的形式抛出,但是也有一些情况会当做异常和错误同时抛出(据说是,我没有找到合适的例子)。也就是说,你想在数据库连接失败的时候自动捕获异常是行不通的,因为这就不是异常,是错误。但是在java中就不一样了,他会把很多和预期不一致的行为当做异常来进行捕获。
5、php中数据库连接失败是错误还是异常?是错误,在php中是错误数据库连接失败的时候自动捕获异常是行不通的,因为这就不是异常,是错误
6、java中的异常指什么?和预期不一致java会把很多和预期不一致的行为当做异常来进行捕获。
7、php通过哪几个函数可以实现PHP假自动捕获异常和错误?register_shutdown_function:捕获PHP的错误:Fatal Error、Parse Error等,这个方法是PHP脚本执行结束前最后一个调用的函数,比如脚本错误、die()、exit、异常、正常结束都会调用set_error_handler:捕获错误,设置一个用户自定义的错误处理函数set_exception_handler:设置默认的异常处理程序,用在没有用try/catch块来捕获的异常,也就是说不管你抛出的异常有没有人捕获,如果没有人捕获就会进入到该方法中,并且在回调函数调用后异常会中止。
8、php中的错误类型有哪几种?Fatal Error:致命错误(脚本终止运行)Parse Error:编译时解析错误,语法错误(脚本终止运行)Warning Error:警告错误(仅给出提示信息,脚本不终止运行)Notice Error:通知错误(仅给出通知信息,脚本不终止运行)
9、框架中的try-catch和php原生中的try-catch是否一样?不一样,比如错误,原生的try-catch不能抛出,但是框架中的可以,框架中为我们扩展了try-catch功能
10、把错误以异常的形式抛出实例?使用set_error_handler函数调用自定义异常处理函数<?php set_error_handler('zyferror'); function zyferror($type, $message, $file, $line) { throw new \Exception($message . 'zyf错误当做异常'); } $num = 0; try { echo 1/$num; } catch (Exception $e){ echo $e->getMessage(); } ?> 好了,试一下,会打印出: Division by zero zyf123 流程:本来是除0错误,然后触发set_error_handler(),在set_error_handler()中相当与杀了个回马枪,再把错误信息以异常的形式抛出来,这样就可以实现错误以异常的形式抛出。大家要注意:这样做是有缺点的,会受到set_error_handler()函数捕获级别的限制。
11、原生php中try-catch如何捕获所有错误?set_error_handler()和register_shutdown_function()由set_error_handler()可知,他能够捕获一部分错误,不能捕获系统级E_ERROR、E_PARSE等错误,但是这部分可以由register_shutdown_function()捕获。 a.php内容: <? // 模拟Fatal error错误 //test(); // 模拟用户产生ERROR错误 //trigger_error('zyf-error', E_USER_ERROR); // 模拟语法错误 var_dump(23+-+); // 模拟Notice错误 //echo $f; // 模拟Warning错误 //echo '123'; //ob_flush(); //flush(); //header("Content-type:text/html;charset=gb2312"); ?>
12、如何自定义异常处理类?继承原先的 exception 类该类必须是 exception 类的一个扩展,该类继承了 PHP 的 exception 类的所有属性,并且我们可以添加自定义的函数,使用的时候其实和之前的一样 <?php class zyfException extends Exception { public function errorzyfMessage() { return 'Error line ' . $this->getLine().' in ' . $this->getFile() .': <b>' . $this->getMessage() . '</b> Must in (0 - 60)'; } } $age = 10; try { $age = intval($age); if($age > 60) { throw new zyfException($age); } } catch (zyfException $e) { echo $e->errorzyfMessage(); } ?>
13、php中异常如何嵌套?分层传递:try 块中可以定义多个异常捕获,然后分层传递异常,理解和冒泡差不多抛给上层:catch中再抛出异常给上层分层传递:try 块中可以定义多个异常捕获,然后分层传递异常,理解和冒泡差不多 <?php $age = 10; try { $age = intval($age); if($age > 60) { throw new zyfException($age); } if ($age <= 0) { throw new Exception($age . ' must > 0'); } } catch (zyfException $e) { echo $e->errorzyfMessage(); } catch(Exception $e) { echo $e->getMessage(); } ?> 抛给上层:catch中再抛出异常给上层 <?php $age = 100; try { try { $age = intval($age); if($age > 60) { throw new Exception($age); } } catch (Exception $e) { throw new zyfException($age); } } catch (zyfException $e) { echo $e->errorzyfMessage(); } ?>
二、再谈PHP错误与异常处理(转)转自:再谈PHP错误与异常处理 结合项目中遇到的PHP异常处理问题,重新梳理了之前模糊的概念,希望对大家理解PHP异常处理有所帮助。 请一定要注意,没有特殊说明:本例 PHP Version < 7 1 <?php 2 $num = 0; 3 try { 4 echo 1/$num; 我的问题是:这段程序能正确的捕捉到除0的错误信息吗? 本文章分5个部分介绍我的异常处理的理解: 一、异常与错误的概述PHP中什么是异常: 上面的说法是有前提条件的: PHP异常处理很鸡肋?
二、ERROR的级别只有熟悉错误级别才能对错误捕捉有更好的认识。 ERROR有不同的错误级别,我之前的一篇文章中有写到:http://www.cnblogs.com/zyf-zhaoyafei/p/3649434.html 1 Fatal Error:致命错误(脚本终止运行) 2 E_ERROR // 致命的运行错误,错误无法恢复,暂停执行脚本 3 E_CORE_ERROR // PHP启动时初始化过程中的致命错误 4 E_COMPILE_ERROR // 编译时致命性错,就像由Zend脚本引擎生成了一个E_ERROR 5 E_USER_ERROR // 自定义错误消息。像用PHP函数trigger_error(错误类型设置为:E_USER_ERROR) 6 7 Parse Error:编译时解析错误,语法错误(脚本终止运行) 8 E_PARSE //编译时的语法解析错误 9 10 Warning Error:警告错误(仅给出提示信息,脚本不终止运行) 11 E_WARNING // 运行时警告 (非致命错误)。 12 E_CORE_WARNING // PHP初始化启动过程中发生的警告 (非致命错误) 。 13 E_COMPILE_WARNING // 编译警告 14 E_USER_WARNING // 用户产生的警告信息 15 16 Notice Error:通知错误(仅给出通知信息,脚本不终止运行) 17 E_NOTICE // 运行时通知。表示脚本遇到可能会表现为错误的情况. 18 E_USER_NOTICE // 用户产生的通知信息。 由此可知有5类是产生ERROR级别的错误,这种错误直接导致PHP程序退出。 1 ERROR = E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_PARSE
三、PHP异常处理中的黑科技前面提到框架中是可以捕获所有的错误和异常的,之所以能实现应该是使用了黑科技,哈哈!其实也不是什么黑科技,主要是三个重要的函数: 1:set_error_handler() 1 <?php 2 set_error_handler('zyferror'); 3 function zyferror($type, $message, $file, $line) 4 { 5 var_dump('<b>set_error_handler: ' . $type . ':' . $message . ' in ' . $file . ' on ' . $line . ' line .</b><br />'); 6 } 7 ?> 当程序出现错误的时候自动调用此方法,不过需要注意一下两点:第一,如果存在该方法,相应的error_reporting()就不能在使用了。所有的错误都会交给自定义的函数处理。第二,此方法不能处理以下级别的错误:E_ERROR、 E_PARSE、 E_CORE_ERROR、 E_CORE_WARNING、 E_COMPILE_ERROR、 E_COMPILE_WARNING,set_error_handler() 函数所在文件中产生的E_STRICT,该函数只能捕获系统产生的一些Warning、Notice级别的错误。 1 <?php 2 // 直接传函数名 NonClassFunction 3 set_error_handler('function_name'); 4 5 // 传 class_name && function_name 6 set_error_handler(array('class_name', 'function_name')); 7 ?> 2:register_shutdown_function() 1 <?php 2 register_shutdown_function('zyfshutdownfunc'); 3 function zyfshutdownfunc() 4 { 5 if ($error = error_get_last()) { 6 var_dump('<b>register_shutdown_function: Type:' . $error['type'] . ' Msg: ' . $error['message'] . ' in ' . $error['file'] . ' on line ' . $error['line'] . '</b>'); 7 } 8 } 9 ?> 通过这种方法就可以巧妙的打印出程序结束前所有的错误信息。但是我在测试的时候我发现并不是所有的错误终止后都会调用这个函数,可以看下面的一个测试文件,内容是: 1 <?php 2 register_shutdown_function('zyfshutdownfunc'); 3 function zyfshutdownfunc() 4 { 5 if ($error = error_get_last()) { 6 var_dump('<b>register_shutdown_function: Type:' . $error['type'] . ' Msg: ' . $error['message'] . ' in ' . $error['file'] . ' on line ' . $error['line'] . '</b>'); 7 } 8 } 9 var_dump(23+-+); //此处语法错误 10 ?> 自己可以试一下,你可以看到根本就不会触发zyfshutdownfunc()函数,其实这是一个语法错误,直接报了一个: 1 <?php 2 Parse error: syntax error, unexpected ')' in /www/mytest/exception/try-catch.php on line 71 3 ?> 由此引出一个奇葩的问题:问什么不能触发,为什么框架中是可以的?其实原因很简单,只在parse-time出错时是不会调用本函数的。只有在run-time出错的时候,才会调用本函数,我的理解是语法检查器前没有执行register_shutdown_function()去把需要注册的函数放到调用的堆栈中,所以就根本不会运行。那框架中为什么任何错误都能进入到register_shutdown_function()中呢,其实在框架中一般会有统一的入口index.php,然后每个类库文件都会通过include ** 的方式加载到index.php中,相当与所有的程序都会在index.php中聚集,同样,你写的具有语法错误的文件也会被引入到入口文件中,这样的话,调用框架,执行index.php,index.php本身并没有语法错误,也就不会产生parse-time错误,而是 include 文件出错了,是run-time的时候出错了,所以框架执行完之后就会触发register_shutdown_function(); 1 a.php文件 2 <?php 3 // 模拟语法错误 4 var_dump(23+-+); 5 ?> 6 7 b.php文件 8 <?php 9 register_shutdown_function('zyfshutdownfunc'); 10 function zyfshutdownfunc() 11 { 12 if ($error = error_get_last()) { 13 var_dump('<b>register_shutdown_function: Type:' . $error['type'] . ' Msg: ' . $error['message'] . ' in ' . $error['file'] . ' on line ' . $error['line'] . '</b>'); 14 } 15 } 16 require 'a.php'; 17 ?> 3:set_exception_handler() 1 <?php 2 set_exception_handler('zyfexception'); 3 function zyfexception($exception) 4 { 5 var_dump("<b>set_exception_handler: Exception: " . $exception->getMessage() . '</b>'); 6 } 7 throw new Exception("zyf exception"); 8 ?>
四、巧妙的捕获错误和异常1:把错误以异常的形式抛出(不能完全抛出) 1 <?php 2 set_error_handler('zyferror'); 3 function zyferror($type, $message, $file, $line) 4 { 5 throw new \Exception($message . 'zyf错误当做异常'); 6 } 7 8 $num = 0; 9 try { 10 echo 1/$num; 11 12 } catch (Exception $e){ 13 echo $e->getMessage(); 14 } 15 ?> 好了,试一下,会打印出: 1 Division by zero zyf123
流程:本来是除0错误,然后触发set_error_handler(),在set_error_handler()中相当与杀了个回马枪,再把错误信息以异常的形式抛出来,这样就可以实现错误以异常的形式抛出。大家要注意:这样做是有缺点的,会受到set_error_handler()函数捕获级别的限制。 1 a.php内容: 2 <? 3 // 模拟Fatal error错误 4 //test(); 5 6 // 模拟用户产生ERROR错误 7 //trigger_error('zyf-error', E_USER_ERROR); 8 9 // 模拟语法错误 10 var_dump(23+-+); 11 12 // 模拟Notice错误 13 //echo $f; 14 15 // 模拟Warning错误 16 //echo '123'; 17 //ob_flush(); 18 //flush(); 19 //header("Content-type:text/html;charset=gb2312"); 20 ?> 到此就可以解释开头的那个程序了吧,test.php 如果是单文件执行是不能捕获到错误的,如果你在框架中执行就是可以的,当然你按照我上面介绍的来扩展也是可以的。
五、自定义异常处理和异常嵌套1:自定义异常处理 在复杂的系统中,我们往往需要自己捕获我们需要特殊处理的异常,这些异常可能是特殊情况下抛出的。所以我们就自己定义一个异常捕获类,该类必须是 exception 类的一个扩展,该类继承了 PHP 的 exception 类的所有属性,并且我们可以添加自定义的函数,使用的时候其实和之前的一样,大致写法如下: 1 <?php 2 class zyfException extends Exception 3 { 4 public function errorzyfMessage() 5 { 6 return 'Error line ' . $this->getLine().' in ' . $this->getFile() 7 .': <b>' . $this->getMessage() . '</b> Must in (0 - 60)'; 8 } 9 } 10 11 $age = 10; 12 try { 13 $age = intval($age); 14 if($age > 60) { 15 throw new zyfException($age); 16 } 17 18 } catch (zyfException $e) { 19 echo $e->errorzyfMessage(); 20 21 } 22 ?> 2:异常嵌套 异 |
2022-08-17
2022-11-06
2022-08-17
2022-07-18
2022-07-29
请发表评论