深入解析PHP中的错误与异常:处理机制与应对策略
在学习PHP的过程中,我们会接触到两个概念,一是错误,二是异常。我勒个去?它们不是同一个东西吗?如果你接触过Java、C#等纯粹的面向对象语言,可能不会遇到异常的问题。毕竟所有的问题都可以通过try...catch来解决。但对于像PHP这样从面向过程发展到面向对象的语言来说,错误和异常是完全不同的两件事。

我们将通过一系列的文章来彻底了解PHP中的错误和异常是什么,处理这些错误和异常的机制是什么,以及我们应该如何对待它们。
什么是错误?
错误一般都是PHP本身的因素造成的。语法错误、环境配置不当等都会导致错误。该错误与 php.ini 文件中的 error_reporting 参数直接相关。这个参数相信大家都配置过。一般配置为E_ALL & ~E_NOTICE。这意味着什么?我们先来看看PHP中有哪些错误类型:
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 //用户生成的通知信息。
配置文件中的E_ALL & ~E_NOTICE表示显示除通知错误之外的所有错误。当然,我们也可以手动更改代码中的错误消息通知。
错误报告(E_ALL);
通过这行代码,我们将显示当前文件代码中的所有错误。注意和警告类型的错误不会中断代码的运行。它们是通知和警报,而不是致命错误。其他类型的错误会中断代码执行。
$a = 100 / 0; // 警告:除以零
回声 $f; // 注意:未定义的变量:f
测试(); // 致命错误:未捕获错误:调用未定义的函数 test()
回声1;
上面的代码是Warning的除零错误警告和echo $f;的未定义变量提示。这两行代码报错后都可以继续运行。未定义的方法是致命级别的致命错误。所以最后的1不会被输出。
那么如何处理错误呢?原则上我们应该消除这些错误,因为它们基本上不是我们代码编写逻辑导致的逻辑错误,而是实际的语法和环境错误。在生产环境中是不允许出现这种错误的。应该出现。同时,它们与异常最重要的区别之一是它们不能通过try...catch捕获。也就是说,这种错误没有非常好的错误后处理机制。
尝试 {
$a = 100 / 0; // 警告:除以零
回声 $f; // 注意:未定义的变量:f
} catch (Excepiton $e) {
打印_r($e); // 无法捕获
不过PHP还是提供了一些错误处理函数供我们使用。
设置错误处理程序()
基本上它只能处理警告和通知级别的错误。
set_error_handler(函数( $errno , $errstr ){
echo 'set_error_handler:', $errno, $errstr, PHP_EOL;
});
$a = 100 / 0; // 警告:除以零
回声 $f; // 注意:未定义的变量:f
测试(); // 致命错误:未捕获错误:调用未定义的函数 test()
// set_error_handler: 2除以零
// set_error_handler: 8未定义变量: f
从代码中可以看出,Fatal error等致命错误没有被捕获。
注册关闭函数()
事实上,它并不是用来处理错误的。该函数的作用是发生致命错误时程序停止之前将调用的最后一个函数。它可以用来记录日志或者关闭一些重要的外部句柄。但在生产环境中,我们一般使用php.ini中的log_error来记录日志。所以这个功能用的不多。
注册_关闭_函数(函数(){
echo 'register_shutdown_function:', PHP_EOL;
print_r(error_get_last());
});
测试();
// 注册关闭函数:
// 大批
//(
// [类型] => 1
// [message] => 未捕获的错误:调用/php/202002/source/中未定义的函数test() 一起了解PHP错误和异常(1).php:16
// 堆栈跟踪:
// #0 {主要}
// 抛出
// [file] => /php/202002/source/一起了解PHP错误与异常(1).php
// [行] => 16
// )
该函数的回调函数中没有参数变量,因此我们需要使用error_get_last()来获取本次执行中发生的所有错误情况。另外需要注意的是,只有运行时产生的错误才会被调用到这个注册函数的回调中。该函数无法捕获编译时错误,例如直接语法错误:
注册_关闭_函数(函数(){
echo 'register_shutdown_function:', PHP_EOL;
print_r(error_get_last());
});
测试(a+-); // 解析错误:语法错误,意外的 ')'
总结
综上所述,正如文章前面提到的,在生产环境中应该尽可能避免错误。他们没有一个好的处理机制。换句话说,错误是我们应该尽量避免的,因为大多数情况下它们与我们的逻辑代码无关。而且,严重错误会直接导致程序运行中止,无法像异常那样通过catch机制保证程序继续运行。
下一篇我们将继续学习下一个知识点:异常及其处理机制。
===========
您可以在各媒体平台搜索【硬核项目经理】