PHP的异常处理机制:
异常的概念:
程序在运行的过程中,出现了不符合预期的情况,即允许发生,但是按照正常的逻辑不应该出现的这种情况,一般都是数据的异常,但这种情况在正常的生产环境中很难遇到但是无法避免,属于业务逻辑和业务流程的错误,而不是程序的语法或解析的错误,我们称之为异常。
错误的概念:
属于php脚本自身的问题,如语法错误,会导致编辑器无法通过检查甚至无法运行的情况,warning,notice对php来说都属于错误,只是级别不同而已,需要注意的是错误是不能被try-catch语法捕获的
(Tip:上述只是针对php语言,不一定适用于其他语言的定义)
小结:
在php语法中,代码中任何语法的错误或非正常代码,都会被当成错误抛出,而且不会被异常捕获,也就是说,你想在链接数据库的时候,自动捕获异常,是行不通的,因为这不属于异常,而是属于错误。
PHP中的ERROR级别:
Fatal Error:致命错误(脚本终止运行)
E_ERROR // 致命的运行错误,错误无法恢复,暂停执行脚本
E_CORE_ERROR // PHP启动时初始化过程中的致命错误
E_COMPILE_ERROR // 编译时致命性错,就像由Zend脚本引擎生成了一个E_ERROR
E_USER_ERROR // 自定义错误消息。像用PHP函数trigger_error(错误类型设置为:E_USER_ERROR)
Parse Error:编译时解析错误,语法错误(脚本终止运行)
E_PARSE //编译时的语法解析错误
Warning Error:警告错误(仅给出提示信息,脚本不终止运行)
E_WARNING // 运行时警告 (非致命错误)。
E_CORE_WARNING // PHP初始化启动过程中发生的警告 (非致命错误) 。
E_COMPILE_WARNING // 编译警告
E_USER_WARNING // 用户产生的警告信息
Notice Error:通知错误(仅给出通知信息,脚本不终止运行)
E_NOTICE // 运行时通知。表示脚本遇到可能会表现为错误的情况.
E_USER_NOTICE // 用户产生的通知信息。
PHP中异常处理中的黑科技:
1,set_error_handler():
用于捕获异常错误,设置一个用户自定义的错误处理函数
<?php
set_error_handler('testByBrady');
function testByBrady($type, $message, $file, $line){
print_r('set error handler:'.$type . ':' . $message . ' in ' . $file . ' on ' . $line . ' line);
}
使用此方法的时候,需要注意的是:
1,不能再使用error_reporting(),因为所有的错误都会有此自定义的函数进行处理
2,此方法只能处理warning/notice级别的错误,无法出库error级别的错误
2,register_shutdown_function():
捕获php程序中的error级别的错误,这个方法是php脚本执行结束之后,最后一个调用的函数,比如脚本错误,异常退出(die,exit),脚本正常结束的时候,都是会主动调用此方法的。
该函数经常配合error_get_last()使用
error_get_last():可以拿到本次执行产生的所有错误。返回的信息类型如下:
[type] - 错误类型
[message] - 错误消息
[file] - 发生错误所在的文件
[line] - 发生错误所在的行
<?php
register_shutdown_function('testByBrady');
function testByBrady($data){
if(error_get_last()){
echo '执行程序中存在error级别的错误!';
}
}
Tip:该函数只会在程序执行过程中或程序结束的时候调用,如果是代码语法的错误,导致无法通过编辑器的检查,则不会触发此函数。
3,set_exception_handler():
设置默认的异常处理程序,用在没有用try-catch块来捕获的异常,也就是说,如果代码抛出得到程序异常没有被其他人捕获,则会自动调用次函数的回调方法,来处理异常。
PHP7版本的异常处理:
在PHP7版本中,更多的error错误变为可捕获的Exception,现在的PHP7实现了一个全局的throwable接口
PHP7的异常层次树:
Throwable
Exception 异常
...
Error 错误
ArithmeticError 算数错误
DivisionByZeroError 除数为0的错误
AssertionError 声明错误
ParseError 解析错误
TypeError 类型错误