乐趣区

关于php:一起搞懂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 就是显示所有谬误但告诉谬误类谬误除外的意思。当然,咱们在代码中也能够手动的扭转这种错误信息的告诉。

error_reporting(E_ALL);

通过这行代码,咱们就让以后文件代码中的谬误全副显示进去了。Notice 和 Warning 类型的谬误是不会中断代码运行的,他们是告诉和报警,并不是致命的谬误。而其余类型的谬误则会中断代码的执行。

$a = 100 / 0; // Warning: Division by zero
echo $f; // Notice: Undefined variable: f 
test(); // Fatal error: Uncaught Error: Call to undefined function test()

echo 1;

上述代码中别离是 Warning 的除 0 谬误正告和 echo $f; 的未定义变量提醒,这两行代码都是能够在报错后能够持续向下运行的。而未定义的办法则是 Fatal 级别的致命谬误了。所以最初那个 1 也不会输入了。

那么谬误要如何解决呢?原则上咱们应该是要去毁灭这些谬误的,因为他们基本上不会是咱们写代码的逻辑没理清而产生的逻辑谬误,是实打实的一些语法及环境谬误,这种谬误在生产环境是不应该呈现的。同时,它们与异样最最重要的一个区别就是,它们无奈通过 try…catch 进行捕捉。也就是说,这种谬误没有十分好的谬误后处理机制。

try {
    $a = 100 / 0; // Warning: Division by zero
    echo $f; // Notice: Undefined variable: f 
} catch (Excepiton $e) {print_r($e); // 无奈捕捉
} 

不过,PHP 还是提供了一些处理错误的函数供咱们应用。

  1. set_error_handler()

基本上只能解决 Warning 和 Notice 级别的谬误。

set_error_handler(function( $errno , $errstr){echo 'set_error_handler:', $errno, $errstr, PHP_EOL;});
$a = 100 / 0; // Warning: Division by zero
echo $f; // Notice: Undefined variable: f 
test(); // Fatal error: Uncaught Error: Call to undefined function test()

// set_error_handler:2Division by zero
// set_error_handler:8Undefined variable: f

从代码中能够看出,Fatal error 这种致命谬误并没有捕捉到。

  1. register_shutdown_function()

其实它也不是用来处理错误的,这个函数的作用是在产生致命谬误,程序进行前最初会调用的一个函数。能够用来记录日志或者敞开一些重要的内部句柄,不过在生产环境中,咱们个别会用 php.ini 中的 log_error 来进行日志的记录。所以这个函数也用得并不多。

register_shutdown_function(function(){
    echo 'register_shutdown_function:', PHP_EOL;
    print_r(error_get_last());
});
test();

// register_shutdown_function:// Array
// (//     [type] => 1
//     [message] => Uncaught Error: Call to undefined function test() in /php/202002/source/ 一起搞懂 PHP 的谬误和异样(一).php:16
// Stack trace:
// #0 {main}
//   thrown
//     [file] => /php/202002/source/ 一起搞懂 PHP 的谬误和异样(一).php
//     [line] => 16
// )

这个函数的回调函数中没有任何的参数变量,所以咱们须要通过 error_get_last() 来拿到本次执行中产生的所有谬误状况。另外要留神的是,只有在运行时产生的谬误都会调用到这个注册函数的回调中,编译时的谬误是也是无奈通过这个函数捕捉到的,比方间接的语法错误:

register_shutdown_function(function(){
    echo 'register_shutdown_function:', PHP_EOL;
    print_r(error_get_last());
});

test(a+-); // Parse error: syntax error, unexpected ')' 

总结

综上所述,就像在文章后面说过的,谬误是应该尽量不要带到生产环境中去的,它们并没有很好的解决机制。或者说,谬误就是咱们要尽量避免的货色,因为大部分状况下它和咱们的逻辑代码并没有太大的关系。而且重大的谬误会间接导致程序运行的停止,无奈像异样一样通过 catch 机制保障程序持续运行。

下一篇咱们将持续学习下一个知识点:异样 及其解决机制。

测试代码:
https://github.com/zhangyue0503/dev-blog/blob/master/php/202002/source/%E4%B8%80%E8%B5%B7%E6%90%9E%E6%87%82PHP%E7%9A%84%E9%94%99%E8%AF%AF%E5%92%8C%E5%BC%82%E5%B8%B8%EF%BC%88%E4%B8%80%EF%BC%89.php

参考文档:
https://www.cnblogs.com/zyf-zhaoyafei/p/6928149.html
https://www.php.net/manual/zh/language.errors.basics.php
https://www.php.net/manual/zh/errorfunc.constants.php
https://www.php.net/manual/zh/errorfunc.configuration.php#ini.error-reporting
https://www.php.net/manual/zh/function.error-reporting.php
https://www.php.net/manual/zh/function.set-error-handler.php
https://www.php.net/manual/zh/function.register-shutdown-function.php

===========

各自媒体平台均可搜寻【硬核项目经理】

退出移动版