【问题标题】:Deprecation warning not catchable in PHP 7.4PHP 7.4 中无法捕获弃用警告
【发布时间】:2020-04-24 10:06:01
【问题描述】:

在 PHP 7.4.0 中,我看到以下警告:
Deprecated: Array and string offset access syntax with curly braces is deprecated in ...
我的错误/异常处理程序无法捕获和记录它们。

示例:

<?php
    set_error_handler(function ($errNo, $errStr) {
        echo "set_error_handler: " . $errStr;
    });

    set_exception_handler(function ($exception) {
        echo "set_exception_handler: " . $exception->getMessage();
    });

    $b = 'test';
    $a = $b{1};

警告仍然显示在正常输出中,并且没有调用两个处理程序。

我想在我自己的日志中记录所有错误、异常和警告,但处理程序没有捕获到这个警告。是否有这样做的原因或解决方案来捕获并记录 PHP 抱怨的所有内容(无法访问服务器 Apache/PHP 日志)?

【问题讨论】:

  • 可能是因为这是在解析过程中检测到的,而不是在运行时检测到的。
  • Related question (不标记为骗子以防万一,因为 0 upvote + 没有亲自尝试答案中给出的方法)
  • @Jeto:链接的答案不起作用,因为在我的案例/示例中从未调用过处理程序。
  • 有很多错误无法用set_error_handler() 捕获:以下错误类型不能用用户定义的函数处理:E_ERROR、E_PARSE、E_CORE_ERROR、E_CORE_WARNING、E_COMPILE_ERROR、 E_COMPILE_WARNING,以及在调用 set_error_handler() 的文件中引发的大部分 E_STRICT。 所以你不应该依赖它来向用户隐藏错误。

标签: php php-7.4


【解决方案1】:

set_error_handler 根据文档捕获运行时发出的消息:

此函数可用于定义您自己在运行时处理错误的方式

您看到的弃用警告是 implemented at compile-time,根据定义,它发生在运行时之前:

static zend_op *zend_delayed_compile_dim(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
{
    if (ast->attr == ZEND_DIM_ALTERNATIVE_SYNTAX) {
        zend_error(E_DEPRECATED, "Array and string offset access syntax with curly braces is deprecated");
    }
    ...

您可能会将其视为“软语法错误”:它是在解析时、在编译步骤中发现的,但不是硬性致命错误,而是对未来厄运的警告。与语法错误一样,您有两种处理方式:前置处理和关闭处理。

预置

$ cat error-handler.php
<?php
set_error_handler(fn(...$args) => var_dump($args));
$ cat try.php
<?php
$b = 'test';
$a = $b{1};
$ php -d auto_prepend_file=error-handler.php try.php
array(5) {
  [0]=>
  int(8192)
  [1]=>
  string(69) "Array and string offset access syntax with curly braces is deprecated"
  [2]=>
  string(21) "/Users/bishop/try.php"
  [3]=>
  int(3)
  [4]=>
  NULL
}

关机处理

register_shutdown_function(fn() => var_dump(error_get_last()));

$b = 'test';
$a = $b{1};

输出:

array(4) {
  ["type"]=>
  int(8192)
  ["message"]=>
  string(69) "Array and string offset access syntax with curly braces is deprecated"
  ["file"]=>
  string(9) "/in/212CF"
  ["line"]=>
  int(7)
}

使用哪个?

根据您的需要选择一个或两个。就个人而言,我使用 prepend 方法,因为它可以处理各种其他白屏死机场景。如果您在 Web 环境中执行此操作,则需要安排您的 Web 服务器以设置 auto_prepend_file 设置:一旦您的“主”代码运行,您就无法设置 prepend 并让它像这里演示的那样工作。

【讨论】:

  • 优秀的答案; prepending flag 很值得了解,而且也很有意义。它也比关闭回调要好得多,它只会“捕获”最后一个错误(特别是在这种情况下,因为那些是非阻塞通知)。
  • trigger_error(E_USER_DEPRECATED) 是这样吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-16
  • 1970-01-01
  • 2022-01-16
  • 2023-02-24
  • 2022-12-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多