php中的异常和错误浅析


Posted in PHP onMay 03, 2017

本文主要介绍了php中的异常和错误,分享给大家供大家参考学习,下面来一起看看详细的介绍:

一、异常与错误

异常是指程序运行中不符合预期情况以及与正常流程不同的状况。错误则属于自身问题,是一种非法语法或者环境问题导致的、让编译器无法通过检查设置无法运行的情况。

由于php最开始是没有异常处理,后来为了进军企业级开发,模仿java等语言,推出了异常。导致php中遇到任何自身错误都会触发一个错误,而不是抛出一个异常(某些情况下,会同时抛出错误和异常)。PHP一旦遇到非正常代码,大多数情况下,都是直接抛出错误,而不是异常。

php只有在你throw 一个异常后,才能用try...catch来捕获异常(一般情况下如此,也有部分异常可以自动捕获)。

在php中通常会在以下场景中使用异常:

     1. 对程序的悲观预测:如果认为自己的代码无法一一处理各种可预见的情况、不可预见的情况。

     2.  程序的需要和对业务的关注 : 如果对数据的一致性要求很高时,可以用try...catch把异常造成的逻辑中断破坏将到最小,并且经过补救处理后,不影响业务逻辑的完整性。

     3. 语言级别的健壮性要求 : 通过精确控制运行时的流程,在程序中断时,有预见的用try...catch缩小可能出错的范围,及时捕获异常并做出相应的补救。

二、怎样看待php的异常

历史原因导致php的异常处理是不足的,绝大多数情况下,无法自动抛出异常,必须使用if...else先进行判断,再手动抛出异常。

手动抛出异常的意义不是很大,因为这意味着在代码里已经充分的预期到错误的出现。同时这种方式还会让你在复杂的逻辑判断和处理中晕头转向。导致失去异常真正的优点。

那么有更好的异常抛出方法吗?有,那就是结合使用错误

三、php中的错误

错误就是会使脚本运行不正常的情况。

在php中主要的错误等级如下:

      1. deprecated: 最低级别的错误,表示"不推荐, 不建议"。例如在php 5中使用了ereg系列的正则函数就会出现。这类错误一般由于使用了不推荐的、过时的函数或语法造成。不影响程序正常运行,但建议修正。

      2. notice: 一般指语法中存在不恰当的地方。如使用变量但是未定义就会报此错误。不影响程序正常流程。

      3. warning: 较高级别的错误,在语法中出现很不恰当的情况才会出现此错误,比如函数参数不匹配。会导致得不到预期的结果,需要修改代码。

      4. fetal error: 致命错误,直接导致程序终止运行。这类错误必须修改。

      5. prase error: 语法解析错误,上面几种都属于运行时错误,此错误在运行前就会抛出。

在php中,总共有16错误级别,但是主要的就是上面几种。

error.php

$data = '2012-12-20';
if (ereg("([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})", $data, $regs)) { 
 echo "$reg[3].$regs[2].$regs[1]";
} else {
 echo "Invalid data format: $data";
}

$a = array('o' => 2, 4, 6, 8);
echo $a[o]; 
$result = array_sum($a, 3);
echo func();

echo '致命错误后,还会执行吗?'; 
//echo '最高级别错误', $55;

上面代码执行后,会有四个错误级别,如果你无法完全看到的话,你需要去修改你的ini配置文件中错误显示级别为 E_ALL

四、自定义错误处理程序

可以使用 set_error_handler() 函数来托管错误处理程序,可自行定制错误的处理流程。

如果要取消托管的话,可以在同一个页面中使用restore_error_handler()来取消托管。

如果想要自己抛出一个错误的话,可以使用trigger_error()函数。

<?php 
//自定义错误处理程序
function customError($errno, $errstr, $errfile, $errline) 
{
 echo "<b>错误代码:</b>[{$errno}] {$errstr}", PHP_EOL;
 echo "错误所在代码行:{$errline} 文件{$errfile}", PHP_EOL;
 echo "PHP版本", PHP_VERSION, "(", PHP_OS, ")", PHP_EOL;
}

set_error_handler("customError", E_ALL | E_STRICT);

$a = array('o' => 2, 4, 6, 8);

echo $a[o];

执行上面的代码,可以看到错误信息是由我们自定义的处理程序输出的,完全绕开了系统的处理程序。

如果错误发生在自定义处理程序前,则不会调用我们自定义的错误处理程序,所以应当先定义错误处理程序。

当然不是所有的错误级别都可以用set_error_handler来托管,如EERROR、EPARSE、ECODEWARNING、ECOMPILEERROR、ECOMPILEWARNING以及E_STRICT中的部分。这些错误信息会以原始的方式来显示或者不现实。

PHP把许多异常看作是错误,所以这些"异常"同样可以使用set_error_handler来接管:

function customError($errno, $errstr, $errfile, $errline) 
{
 //自定义错误处理是,手动抛出异常
 throw new Exception($errstr);
}

set_error_handler('customError', E_ALL | E_STRICT);

try { 
 $a = 5/0;
} catch (Exception $e) {
 echo '错误信息:', $e->getMessage();
}

当然这种处理方式也有自己的优缺点:

       缺点: 必须依靠程序员自己来掌控对异常的处理,对于异常的高发区、敏感区,如果程序员处理不好,就会导致业务数据不一致的问题。

       优点: 可以获得程序运行时的上下文信息,以进行针对性的补救。

fetal error这样的错误无法捕获,也无法在发生后恢复流程处理,但是可以使用register_shutdown_function()函数在程序终止或die时触发一个函数,给程序带来一个短暂的回光返照。在php4时,不支持析构函数,也常用于模拟实现析构函数。

class Shutdown 
{
 public function stop()
 {
 if (error_get_laster()) {
 print_r(error_get_laster());
 }

 die('Stop.');
 }
}

register_shutdown_function(array(new Shutdown(), 'stop'));

$a = new a(); //致命错误,导致失败
echo '必须终止';

Parse error级别的错误,除了修改ini文件,将错误信息写到日志中,什么也做不了。

小结

php中错误和异常是两个不同的概念,这种设计根本上导致了php的异常和错误与其它语言相异。java中,异常时错误唯一的报告方式。说到底,两者的区别就是对异常的认识不同产生的。php异常绝大部分是通过某种方式手动抛出,才能捕获到。是一种半自动化的异常处理机制。

无论是错误还是异常,都可以使用handler接管系统已有的处理机制。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

PHP 相关文章推荐
PHP中的串行化变量和序列化对象
Sep 05 PHP
php-accelerator网站加速PHP缓冲的方法
Jul 30 PHP
php实现的仿阿里巴巴实现同类产品翻页
Dec 11 PHP
PHP5.3的垃圾回收机制(动态存储分配方案)深入理解
Dec 10 PHP
深入探讨<br />和 \r\n两者有什么区别??
Jun 05 PHP
php正则匹配html中带class的div并选取其中内容的方法
Jan 13 PHP
PHP中使用Imagick读取pdf并生成png缩略图实例
Jan 21 PHP
php快速查找数据库中恶意代码的方法
Apr 01 PHP
非常重要的php正则表达式详解
Jan 04 PHP
jquery+thinkphp实现跨域抓取数据的方法
Oct 15 PHP
PHP实现的简单路由和类自动加载功能
Mar 13 PHP
php中用unset销毁变量并释放内存
May 10 PHP
利用php-cli和任务计划实现刷新token功能的方法
May 03 #PHP
利用php-cli和任务计划实现订单同步功能的方法
May 03 #PHP
php删除数组指定元素实现代码
May 03 #PHP
在php7中MongoDB实现模糊查询的方法详解
May 03 #PHP
PHP里面把16进制的图片数据显示在html的img标签上(实现方法)
May 02 #PHP
php 使用curl模拟ip和来源进行访问的实现方法
May 02 #PHP
ThinkPHP实现静态缓存和动态缓存示例代码
May 02 #PHP
You might like
有关 PHP 和 MySQL 时区的一点总结
2008/03/26 PHP
php把数据表导出为Excel表的最简单、最快的方法(不用插件)
2014/05/10 PHP
一键生成各种尺寸Icon的php脚本(实例)
2017/02/08 PHP
JavaScript 乱码问题
2009/08/06 Javascript
利用ajaxfileupload插件实现文件上传无刷新的具体方法
2013/06/08 Javascript
JQuery设置时间段下拉选择实例
2014/12/30 Javascript
url中的特殊符号有什么含义(推荐)
2016/06/17 Javascript
分享JS数组求和与求最大值的方法
2016/08/11 Javascript
微信小程序 Canvas增强组件实例详解及源码分享
2017/01/04 Javascript
jquery.validate表单验证插件使用详解
2017/06/21 jQuery
React教程之Props验证的具体用法(Props Validation)
2017/09/04 Javascript
实例教学如何写vue插件
2017/11/30 Javascript
微信小程序拼接图片链接无底洞深入探究
2019/09/03 Javascript
[05:08]第一届“网鱼杯”DOTA2比赛精彩集锦
2014/09/05 DOTA
Python不规范的日期字符串处理类
2014/06/10 Python
wxPython窗口中文乱码解决方法
2014/10/11 Python
Python的requests网络编程包使用教程
2016/07/11 Python
[原创]python爬虫(入门教程、视频教程)
2018/01/08 Python
Python实现爬虫设置代理IP和伪装成浏览器的方法分享
2018/05/07 Python
Python 中PyQt5 点击主窗口弹出另一个窗口的实现方法
2019/07/04 Python
python之yield和Generator深入解析
2019/09/18 Python
Python如何基于rsa模块实现非对称加密与解密
2020/01/03 Python
Python对Tornado请求与响应的数据处理
2020/02/12 Python
在python3中实现更新界面
2020/02/21 Python
keras .h5转移动端的.tflite文件实现方式
2020/05/25 Python
python能否java成为主流语言吗
2020/06/22 Python
Python学习工具jupyter notebook安装及用法解析
2020/10/23 Python
PUMA官方商城:世界领先的运动品牌之一
2016/11/16 全球购物
Servlet都有哪些方法?主要作用是什么?
2014/03/04 面试题
关于人生的感言
2014/01/17 职场文书
《雨霖铃》教学反思
2014/02/22 职场文书
爱心捐助活动总结
2015/05/09 职场文书
观看建国大业观后感
2015/06/01 职场文书
离婚财产分割协议书
2015/08/11 职场文书
放飞理想主题班会
2015/08/14 职场文书
Vue Mint UI mt-swipe的使用方式
2022/06/05 Vue.js