异常是指程序运行中不符合预期状况以及与正常流程不一样的情况。错误则属于自身问题,是一种非法语法或者环境问题致使的、让编译器没法经过检查设置没法运行的状况。php
因为php最开始是没有异常处理,后来为了进军企业级开发,模仿java等语言,推出了异常。致使php中遇到任何自身错误都会触发一个错误,而不是抛出一个异常(某些状况下,会同时抛出错误和异常)。PHP一旦遇到非正常代码,大多数状况下,都是直接抛出错误,而不是异常。java
php只有在你throw 一个异常后,才能用try...catch来捕获异常(通常状况下如此,也有部分异常能够自动捕获)。
程序员
在php中一般会在如下场景中使用异常:函数
对程序的悲观预测
:若是认为本身的代码没法一一处理各类可预见的状况、不可预见的状况。设计
程序的须要和对业务的关注
: 若是对数据的一致性要求很高时,能够用try...catch把异常形成的逻辑中断破坏将到最小,而且通过补救处理后,不影响业务逻辑的完整性。rest
语言级别的健壮性要求
: 经过精确控制运行时的流程,在程序中断时,有预见的用try...catch缩小可能出错的范围,及时捕获异常并作出相应的补救。日志
历史缘由致使php的异常处理是不足的,绝大多数状况下,没法自动抛出异常,必须使用if...else先进行判断,再手动抛出异常。code
手动抛出异常的意义不是很大,由于这意味着在代码里已经充分的预期到错误的出现。同时这种方式还会让你在复杂的逻辑判断和处理中晕头转向。致使失去异常真正的优势。orm
那么有更好的异常抛出方法吗?有,那就是结合使用错误开发
错误就是会使脚本运行不正常的状况。
在php中主要的错误等级以下:
deprecated:
最低级别的错误,表示"不推荐, 不建议"。例如在php 5中使用了ereg系列的正则函数就会出现。这类错误通常因为使用了不推荐的、过期的函数或语法形成。不影响程序正常运行,但建议修正。
notice:
通常指语法中存在不恰当的地方。如使用变量可是未定义就会报此错误。不影响程序正常流程。
warning:
较高级别的错误,在语法中出现很不恰当的状况才会出现此错误,好比函数参数不匹配。会致使得不到预期的结果,须要修改代码。
fetal error:
致命错误,直接致使程序终止运行。这类错误必须修改。
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
来托管,如E_ERROR、E_PARSE、E_CODE_WARNING、E_COMPILE_ERROR、E_COMPILE_WARNING以及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
接管系统已有的处理机制。