Почему нет ошибки PHP при вызове неопределенной функции?

Всякий раз, когда происходит вызов неопределенной функции, ошибки не регистрируются. Вместо этого скрипт просто перестает выполняться. Что еще хуже, если я запускаю php -l filename.php, он показывает, что синтаксических ошибок нет. Я использую пользовательскую функцию обработчика ошибок, но даже первая строка никогда не достигается.

Как заставить его запускать обработчик ошибок при вызове неопределенной функции?

Я использую PHP 5.3.2-1. Вот код, устанавливающий обработчик ошибок:

error_reporting(-1);
$old_error_handler = set_error_handler( "userErrorHandler" );
set_exception_handler('exception_handler');

Ни обработчик ошибок, ни обработчик исключений не достигаются, хотя они работают для других ошибок.

Причина, по которой я хочу этого, заключается в том, что в конечном итоге мне приходится размещать операторы отладки в моем коде, чтобы увидеть, как далеко он продвинется, прежде чем перестанет выполняться, что является медленным процессом по сравнению с сообщением об ошибке, которое укажет мне файл и номер строки, где ошибка .


person still_dreaming_1    schedule 26.10.2011    source источник


Ответы (2)


Фатальные ошибки не могут быть обнаружены обработчиком ошибок пользователя.

См. http://php.net/manual/en/function.set-error-handler.php

В частности часть:

Следующие типы ошибок не могут быть обработаны с помощью определяемой пользователем функции: E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING и большая часть E_STRICT возникает в файле, где вызывается set_error_handler().

И, согласно комментариям на странице руководства PHP, одним из способов решения проблемы является проверка ошибок в функции выключения:

<?php
    error_reporting(E_ALL);
    ini_set('display_errors', 0);

    function shutdown(){
        $isError = false;
        if ($error = error_get_last()){
            switch($error['type']){
                case E_ERROR:
                case E_CORE_ERROR:
                case E_COMPILE_ERROR:
                case E_USER_ERROR:
                    $isError = true;
                    break;
            }
        }

        if ($isError){
            echo "Script execution halted ({$error['message']})";
        } else {
            echo "Script completed";
        }
    }

    register_shutdown_function('shutdown');
?>
person Petah    schedule 26.10.2011
comment
+1 за полноту (как почему id не работает, так и обходной путь) - person Peter; 26.10.2011
comment
Этот обходной путь отлично работает! Я также добавил следующие случаи в оператор switch на основе документации, на которую вы ссылались: E_PARSE, E_COMPILE_WARNING, E_STRICT. Судя по документации, кажется, что перехват ошибок E_STRICT таким образом иногда приводит к дублированию регистрации ошибок, но это необходимо для регистрации всех ошибок. Я основываюсь на документации, в которой говорится, что большинство ошибок E_STRICT не могут быть обработаны с помощью определяемой пользователем функции. - person still_dreaming_1; 26.10.2011
comment
Кроме того, документация не включает E_USER_ERROR в список типов ошибок, которые не могут быть обработаны определяемой пользователем функцией, поэтому я удалил этот случай из кода, который вы разместили. - person still_dreaming_1; 26.10.2011
comment
В рамках этого обходного пути я также предпочитаю вызывать собственный обработчик ошибок из функции выключения для тех типов ошибок, которые она еще не перехватила. - person still_dreaming_1; 15.02.2015

В руководстве есть соответствующая часть для set_error_handler().

Следующие типы ошибок не могут быть обработаны пользовательской функцией: E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING и большая часть E_STRICT возникает в файле, где вызывается set_error_handler().

person alex    schedule 26.10.2011