捕获php中的错误与异常

关于配置

1、display_errors

; This directive controls whether or not and where PHP will output errors,
; notices and warnings too. Error output is very useful during development, but
; it could be very dangerous in production environments. Depending on the code
; which is triggering the error, sensitive information could potentially leak
; out of your application such as database usernames and passwords or worse.
; For production environments, we recommend logging errors rather than
; sending them to STDOUT.
; Possible Values:
;   Off = Do not display any errors
;   stderr = Display errors to STDERR (affects only CGI/CLI binaries!)
;   On or stdout = Display errors to STDOUT
; Default Value: On
; Development Value: On
; Production Value: Off
; http://php.net/display-errors
display_errors = Off

此配置会将errors,notices,warnings类型的信息发送给标准输出STDOUT,也就是会打印出错误信息,建议开发环境设置为On,正式环境设置为Off

运行时设置ini_set('display_errors', TRUE);

2、error_reporting

; This directive informs PHP of which errors, warnings and notices you would like
; it to take action for. The recommended way of setting values for this
; directive is through the use of the error level constants and bitwise
; operators. The error level constants are below here for convenience as well as
; some common settings and their meanings.
; By default, PHP is set to take action on all errors, notices and warnings EXCEPT
; those related to E_NOTICE and E_STRICT, which together cover best practices and
; recommended coding standards in PHP. For performance reasons, this is the
; recommend error reporting setting. Your production server shouldn't be wasting
; resources complaining about best practices and coding standards. That's what
; development servers and development settings are for.
; Note: The php.ini-development file has this setting as E_ALL. This
; means it pretty much reports everything which is exactly what you want during
; development and early testing.
;
; Error Level Constants:
; E_ALL             - All errors and warnings (includes E_STRICT as of PHP 5.4.0)
; E_ERROR           - fatal run-time errors
; E_RECOVERABLE_ERROR  - almost fatal run-time errors
; E_WARNING         - run-time warnings (non-fatal errors)
; E_PARSE           - compile-time parse errors
; E_NOTICE          - run-time notices (these are warnings which often result
;                     from a bug in your code, but it's possible that it was
;                     intentional (e.g., using an uninitialized variable and
;                     relying on the fact it is automatically initialized to an
;                     empty string)
; E_STRICT          - run-time notices, enable to have PHP suggest changes
;                     to your code which will ensure the best interoperability
;                     and forward compatibility of your code
; E_CORE_ERROR      - fatal errors that occur during PHP's initial startup
; E_CORE_WARNING    - warnings (non-fatal errors) that occur during PHP's
;                     initial startup
; E_COMPILE_ERROR   - fatal compile-time errors
; E_COMPILE_WARNING - compile-time warnings (non-fatal errors)
; E_USER_ERROR      - user-generated error message
; E_USER_WARNING    - user-generated warning message
; E_USER_NOTICE     - user-generated notice message
; E_DEPRECATED      - warn about code that will not work in future versions
;                     of PHP
; E_USER_DEPRECATED - user-generated deprecation warnings
;
; Common Values:
;   E_ALL (Show all errors, warnings and notices including coding standards.)
;   E_ALL & ~E_NOTICE  (Show all errors, except for notices)
;   E_ALL & ~E_NOTICE & ~E_STRICT  (Show all errors, except for notices and coding standards warnings.)
;   E_COMPILE_ERROR|E_RECOVERABLE_ERROR|E_ERROR|E_CORE_ERROR  (Show only errors)
; Default Value: E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
; Development Value: E_ALL
; Production Value: E_ALL & ~E_DEPRECATED & ~E_STRICT
; http://php.net/error-reporting

error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT

此配置是报告哪些错误类型。默认值为E_ALL & ~E_DEPRECATED & ~E_STRICT

其中E_ALL & ~E_NOTICE 等价于 E_ALL ^E_NOTICE,意为报告所有信息,除了E_NOTICE类型。

运行时设置error_reporting(E_ALL ^E_NOTICE);

返回当前的报告级别 error_reporting();

错误码类型:

常量说明备注
1E_ERROR (int)致命的运行时错误。这类错误一般是不可恢复的情况,例如内存分配导致的问题。后果是导致脚本终止不再继续运行。
2E_WARNING (int)运行时警告 (非致命错误)。仅给出提示信息,但是脚本不会终止运行。
4E_PARSE (int)编译时语法解析错误。解析错误仅仅由分析器产生。
8E_NOTICE (int)运行时通知。表示脚本遇到可能会表现为错误的情况,但是在可以正常运行的脚本里面也可能会有类似的通知。
16E_CORE_ERROR (int)在 PHP 初始化启动过程中发生的致命错误。该错误类似 E_ERROR,但是是由 PHP 引擎核心产生的。
32E_CORE_WARNING (int)PHP 初始化启动过程中发生的警告 (非致命错误) 。类似 E_WARNING,但是是由 PHP 引擎核心产生的。
64E_COMPILE_ERROR (int)致命编译时错误。类似 E_ERROR,但是是由 Zend 脚本引擎产生的。
128E_COMPILE_WARNING (int)编译时警告 (非致命错误)。类似 E_WARNING,但是是由 Zend 脚本引擎产生的。
256E_USER_ERROR (int)用户产生的错误信息。类似 E_ERROR,但是是由用户自己在代码中使用 PHP 函数 trigger_error()来产生的。
512E_USER_WARNING (int)用户产生的警告信息。类似 E_WARNING,但是是由用户自己在代码中使用 PHP 函数 trigger_error()来产生的。
1024E_USER_NOTICE (int)用户产生的通知信息。类似 E_NOTICE,但是是由用户自己在代码中使用 PHP 函数 trigger_error()来产生的。
2048E_STRICT (int)启用 PHP 对代码的修改建议,以确保代码具有最佳的互操作性和向前兼容性。PHP 5.4.0 之前的版本中不包含 E_ALL
4096E_RECOVERABLE_ERROR (int)可被捕捉的致命错误。 它表示发生了一个可能非常危险的错误,但是还没有导致PHP引擎处于不稳定的状态。 如果该错误没有被用户自定义句柄捕获 (参见 set_error_handler()),将成为一个 E_ERROR 从而脚本会终止运行。自 PHP 5.2.0 起
8192E_DEPRECATED (int)运行时通知。启用后将会对在未来版本中可能无法正常工作的代码给出警告。自 PHP 5.3.0 起
16384E_USER_DEPRECATED (int)用户产生的警告信息。 类似 E_DEPRECATED, 但是是由用户自己在代码中使用PHP函数 trigger_error()来产生的。自 PHP 5.3.0 起
32767E_ALL (int)PHP 5.4.0 之前为 E_STRICT 除外的所有错误和警告信息。PHP 5.4.x 中为 32767, PHP 5.3.x 中为 30719, PHP 5.2.x 中为 6143, 更早之前的 PHP 版本中为 2047。
try…catch 能做什么

可以捕获异常和错误,在php中有预定义的异常和错误,系统会自动抛出,这些是可以通过try...catch来捕获的。

https://www.php.net/manual/en/reserved.exceptions.php

Exception
ErrorException
Error
ArgumentCountError
ArithmeticError
AssertionError
DivisionByZeroError
CompileError
ParseError
TypeError
ValueError
UnhandledMatchError
FiberError

我们最常用的捕获自定义的异常

try {
    throw new MyException('xxx');
} catch (MyException $e){
    
}

假如我们调用了一个未定义的方法,那么内核会抛出一个预定义的Error,比如Uncaught Error: Call to undefined function checkOrderFormats() in /www/chpay/api/order_status.php:29这是一个E_ERROR类型,会导致程序中止。

此时我们可以这样写

try {
    checkOrderFormats();
    throw new MyException('xxx');
} catch (MyException $e){
    
} catch (Error $e){
    
}

于是我们会发现,php内置的预定义ExceptionError挺多的,再加上我们自定义的Exception,要想通过try...catch来全部捕获他们实在不现实,也不友好。

register_shutdown_function

此函数在php中止时被执行。在这个函数里我们可以获取到没有被try…catch捕获或其他程序处理的错误,并记录到日志文件中。

register_shutdown_function("shutdownLog");

function shutdownLog()
{
	if (!is_null($e = error_get_last())) {
		addLog($e['message'], "ERROR");
	}
}

上面提到的调用了一个未定义的方法会导致程序中止,在此处就可以被捕获到,当然,如果你使用了try...catch捕获了预定义的Error,那么此处就没有了。

set_error_handler

设置用户自定义的错误处理函数,自定义的错误类型指的是E_USER_ERROR,E_USER_WARNING,E_USER_NOTICE

set_error_handler("myErrorHandlerLog", E_ALL ^ E_NOTICE);

function myErrorHandlerLog($errno, $errstr, $errfile, $errline)
{
	addLog(sprintf("[%d] %s in %s:%d", $errno, $errstr, $errfile, $errline), "ERROR");
	return true;
}

此处如果返回false,那么错误信息将会继续向下传导,因此返回true即可。

上面提到的调用了一个未定义的方法(E_ERROR),在此处没有捕获到,另外它还不能捕获E_ERROR、 E_PARSE、 E_CORE_ERROR、 E_CORE_WARNING、 E_COMPILE_ERROR、E_COMPILE_WARNING,以及在调用 set_error_handler() 函数所在文件中产生的大多数 E_STRICT

重要的是要记住 error_types 里指定的错误类型都会绕过 PHP 标准错误处理程序, 除非回调函数返回了 falseerror_reporting() 设置将不会起到作用而你的错误处理函数继续会被调用 —— 不过你仍然可以获取 error_reporting 的当前值,并做适当处理。 需要特别注意的是带 @ error-control operator 前缀的语句发生错误时,这个值会是 0。

但是我发现它能捕获E_WARNING的错误,比如$a = 10 / 0;

总结

最终的错误处理的方式

error_reporting(E_ALL);
ini_set('display_errors', FALSE);

// 位置尽量靠前
register_shutdown_function("shutdownLog");
set_error_handler("myErrorHandlerLog", E_ALL);

function shutdownLog()
{
	if (!is_null($e = error_get_last())) {
		addLog(sprintf("[%d] %s in %s:%d", $e['type'], $e['message'], $e['file'], $e['line']), "ERROR");
	}
}

function myErrorHandlerLog($errno, $errstr, $errfile, $errline)
{
	addLog(sprintf("[%d] %s in %s:%d", $errno, $errstr, $errfile, $errline), "ERROR");
	return true;
}

基本上就能捕获所有的信息了。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值