关于配置
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();
错误码类型:
值 | 常量 | 说明 | 备注 |
---|---|---|---|
1 | E_ERROR (int) | 致命的运行时错误。这类错误一般是不可恢复的情况,例如内存分配导致的问题。后果是导致脚本终止不再继续运行。 | |
2 | E_WARNING (int) | 运行时警告 (非致命错误)。仅给出提示信息,但是脚本不会终止运行。 | |
4 | E_PARSE (int) | 编译时语法解析错误。解析错误仅仅由分析器产生。 | |
8 | E_NOTICE (int) | 运行时通知。表示脚本遇到可能会表现为错误的情况,但是在可以正常运行的脚本里面也可能会有类似的通知。 | |
16 | E_CORE_ERROR (int) | 在 PHP 初始化启动过程中发生的致命错误。该错误类似 E_ERROR ,但是是由 PHP 引擎核心产生的。 | |
32 | E_CORE_WARNING (int) | PHP 初始化启动过程中发生的警告 (非致命错误) 。类似 E_WARNING ,但是是由 PHP 引擎核心产生的。 | |
64 | E_COMPILE_ERROR (int) | 致命编译时错误。类似 E_ERROR ,但是是由 Zend 脚本引擎产生的。 | |
128 | E_COMPILE_WARNING (int) | 编译时警告 (非致命错误)。类似 E_WARNING ,但是是由 Zend 脚本引擎产生的。 | |
256 | E_USER_ERROR (int) | 用户产生的错误信息。类似 E_ERROR ,但是是由用户自己在代码中使用 PHP 函数 trigger_error()来产生的。 | |
512 | E_USER_WARNING (int) | 用户产生的警告信息。类似 E_WARNING ,但是是由用户自己在代码中使用 PHP 函数 trigger_error()来产生的。 | |
1024 | E_USER_NOTICE (int) | 用户产生的通知信息。类似 E_NOTICE ,但是是由用户自己在代码中使用 PHP 函数 trigger_error()来产生的。 | |
2048 | E_STRICT (int) | 启用 PHP 对代码的修改建议,以确保代码具有最佳的互操作性和向前兼容性。 | PHP 5.4.0 之前的版本中不包含 E_ALL |
4096 | E_RECOVERABLE_ERROR (int) | 可被捕捉的致命错误。 它表示发生了一个可能非常危险的错误,但是还没有导致PHP引擎处于不稳定的状态。 如果该错误没有被用户自定义句柄捕获 (参见 set_error_handler()),将成为一个 E_ERROR 从而脚本会终止运行。 | 自 PHP 5.2.0 起 |
8192 | E_DEPRECATED (int) | 运行时通知。启用后将会对在未来版本中可能无法正常工作的代码给出警告。 | 自 PHP 5.3.0 起 |
16384 | E_USER_DEPRECATED (int) | 用户产生的警告信息。 类似 E_DEPRECATED , 但是是由用户自己在代码中使用PHP函数 trigger_error()来产生的。 | 自 PHP 5.3.0 起 |
32767 | E_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内置的预定义Exception
和Error
挺多的,再加上我们自定义的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 标准错误处理程序, 除非回调函数返回了 false
。 error_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;
}
基本上就能捕获所有的信息了。