Предупреждение об устаревании не может быть поймано в PHP 7.4 - PullRequest
6 голосов
/ 07 января 2020

В 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 log)?

1 Ответ

6 голосов
/ 07 января 2020

set_error_handler перехватывает сообщения, отправляемые во время выполнения, в соответствии с документацией:

Эта функция может использоваться для определения собственного способа обработки ошибок во время выполнения

Предупреждение об устаревании, которое вы видите, реализовано во время компиляции , что по определению происходит до времени выполнения:

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, поскольку он обрабатывает различные другие сценарии White Screen of Death ios. Если вы делаете это в веб-контексте, вам нужно настроить свой веб-сервер на установку параметра auto_prepend_file: после запуска «основного» кода вы не сможете установить prepend и заставить его работать, как показано здесь.

...