php7 error log,PHP7升级-异常错误处理

PHP最开始只有错误处理,直到PHP5才借鉴了其他语言,引入了异常处理,但是仍然无法处理致命错误,PHP7以后大部分致命错误和可捕获错误(E_ERROR 和 E_RECOVERABLE_ERROR)发生时会抛出异常,可以捕获,而不是停止脚本执行。但是对于某些情况,比如内存分配导致的问题等还会像原来一样直接停止脚本执行。遗憾的是某些情况官方并没有给出明确的规定。总之PHP的异常错误处理,虽然一直不是很清晰,是一个不断发展完善的过程,希望以后的版本会越来越好。

错误

定义

属于php脚本自身的问题,大部分情况是由错误的语法,服务器环境导致,使得编译器无法通过检查,甚至无法运行的情况。

错误常量说明

错误触发

触发分系统触发和用户触发,用户触发可以通过trigger_error产生一个用户级别的 error/warning/notice 信息,分别对应E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE三种错误

错误处理mixed set_error_handler(callable $error_handler [, int $error_types = E_ALL | E_STRICT ])

注意如下:error_types 里指定的错误类型都会绕过 PHP 标准错误处理程序, 除非回调函数返回了 false。

error_types 里指定的错误类型都会触发,跟error_reporting设置没关系,但是可以根据error_reporting做处理。function _error_handler($errno, $errstr ,$errfile, $errline){    if (error_reporting() & $errno) {        //todo log;

}

}

set_error_handler('_error_handler');注意@前缀语句发生错误时,error_reporting()返回0。@前缀春哥不推荐使用,效率低,而且@用正常错误和异常处理流程完全能搞定。

该函数不会导致脚本退出,会继续执行,所以有需要的话使用die()退出。

该函数目前有些鸡肋,只能处理E_WARNING,E_NOTICE和三种用户错误。以下级别的错误不能由用户定义的函数来处理: E_ERROR、 E_PARSE、 E_CORE_ERROR、 E_CORE_WARNING、 E_COMPILE_ERROR、 E_COMPILE_WARNING,和在 调用 set_error_handler() 函数所在文件中产生的大多数 E_STRICT。对PHP错误处理建议如下配置:一定要让 PHP 报告错误;

在开发环境中要显示错误;

在生产环境中不能显示错误;

在开发和生产环境中都要记录错误。

生产环境:;不显示错误

display_startup_errors = Off

display_errors = Off

;除了NOTICE外,报告所有错误

error_reporting = E_ALL & ~E_NOTICE

; 记录错误

log_errors = On

开发环境:;显示错误

display_startup_errors = On

display_errors = On

;报告所有错误

error_reporting = -1

; 记录错误

log_errors = On

异常

定义

异常也是一中错误,只不过是一中优秀的处理方式,有如下特点:异常可以自定义扩展

异常可以抛出和捕获,开发者能够根据具体的错误,进行相应的后续处理。

异常有调用堆栈信息,方便调试。

未被捕获的异常,将以fatal error 的形式中断脚本的执行并输出错误信息

层级interface Throwable

|- Error implements Throwable

|- ArithmeticError extends Error

|- DivisionByZeroError extends ArithmeticError

|- AssertionError extends Error

|- ParseError extends Error

|- TypeError extends Error

|- ArgumentCountError extends TypeError

|- Exception implements Throwable

|- ClosedGeneratorException extends Exception

|- DOMException extends Exception

|- ErrorException extends Exception

|- IntlException extends Exception

|- LogicException extends Exception

|- BadFunctionCallException extends LogicException

|- BadMethodCallException extends BadFunctionCallException

|- DomainException extends LogicException

|- InvalidArgumentException extends LogicException

|- LengthException extends LogicException

|- OutOfRangeException extends LogicException

|- PharException extends Exception

|- ReflectionException extends Exception

|- RuntimeException extends Exception

|- OutOfBoundsException extends RuntimeException

|- OverflowException extends RuntimeException

|- PDOException extends RuntimeException

|- RangeException extends RuntimeException

|- UnderflowException extends RuntimeException

|- UnexpectedValueException extends RuntimeException

特殊说明:PHP5中一些无法处理的Fatal Error在PHP7中可以作为Error异常处理。

ParseError require或者eval出现语法错误的时候被抛出.

TypeError 函数的传参与其对应的声明参数类型不匹配;函数返回值类型与声明的函数返回类型不匹配。将无效数量的参数传递给内置PHP函数。(strict mode only)

异常处理

try/catch

建议在框架的顶层增加try/catch来未能捕获的异常。

set_exception_handler如果没有用try/catch捕获异常,则会调用该逻辑。

注意与set_error_handler不同的是,该函数调用后会终止脚本。

调用方式如下:set_exception_handler('handle');//方式一set_exception_handler(array('App','handle'));//方式二

PHP7升级的变化

set_exception_handler// 修改前(PHP5代码)set_exception_handler(function (Exception $e) {    echo 'Throw Exception: '.$e->getMessage();

});

// 修改后(同时兼容PHP5和PHP7代码)set_exception_handler(function ($e) {    echo 'Throw Exception: '.$e->getMessage();

});

try/catch// 修改前(PHP5代码)try {    //Code } catch (Exception $e) {    //TODO something}// 修改后(同时兼容PHP5和PHP7代码)try {    //Code } catch (Throwable $t) {    //TODO something} catch (Exception $e) {    //TODO something}

可能会出现的'BUG'

如下写法可能会导致一些问题, require之前最好判断一下is_file,具体详见https://bugs.php.net/bug.php?id=76636

t.php<?phperror_reporting (E_ALL^E_NOTICE);function _exception_handler($e){

var_dump($e);exit(1);

}

set_exception_handler('_exception_handler');

spl_autoload_register(function($className) {

$php = $className . ".php";

$ret = require_once $php;    return true;

});

spl_autoload_register(function($className) {

$php = "namespace\\" . $className . ".php";

$ret = require_once $php;        echo $e->getMessage();        return true;

});new mytest();

mytest.php<?phpclass  mytest {

fdsaf;//parse error}

小结

总之PHP异常是错误的一种,在PHP7中错误可以分为可处理错误(set_error_handler),异常(Exception/Error),不可处理错误。

作者:码路春哥

链接:https://www.jianshu.com/p/0bb87b024b40

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值