Предотвращение исключений без стековых фреймов с обработчиками исключений ошибок и выключения

В течение недели у меня была небольшая проблема. Сообщение об ошибке перед этим:

[30-Dec-2012 15:19:32] PHP Неустранимая ошибка: Исключение выбрано без фрейма стека Неизвестно в строке 0

Я думаю, это потому, что мой обработчик ошибок (см. Ниже для подробностей) превращает любую ошибку в исключение. Я мог бы предотвратить это, если нет рамки стека.

Есть ли простой способ узнать, есть ли какой-либо стек кадров или нет в PHP?

Детали:

На одном из моих веб-сайтов у меня работает обработчик ошибок, который превращает каждую ошибку в исключение, а общее исключение ErrorException должно быть точным.

Я представил его некоторое время назад, потому что сайт – это главным образом унаследованный код, и я хотел, чтобы какая-либо проблема привела к исключению, я могу, наконец, «уловить» упорядоченным способом обработчик исключений и дать остановке.

Я поместил это в свой класс, обработчик зарегистрирован, а также параллельно выходной буфер открыт, чтобы поймать выход до тех пор, пока не будет выбрано исключение. В основном такой код:

 // register output buffering $r = ob_start(array($this, 'handleBuffer')); // register error handler $this->_originalErrorHandler = set_error_handler(array($this, 'handleError')); // register exception handler $this->_originalExceptionHandler = set_exception_handler(array($this, 'handleException')); 

Это работало отлично и денди, пока я не решил добавить еще один класс буферизации вывода в микс. Только тот, который ловит также весь вывод, а затем может делать некоторые «пост-выпуски» на веб-сайте, в том числе проверку на проблемы с HTML (да, это все немного наследие, так что на самом деле это немного утиная лента, я знаю). Это также отлично работает. однако не тогда, когда я допустил ошибку в новом компоненте:

[30-Dec-2012 15:19:32] PHP Неустранимая ошибка: Исключение выбрано без фрейма стека Неизвестно в строке 0

Это в основном моя проблема. Есть ли простой способ предотвратить получение этих ошибок? Я несколько знаю, почему ошибка дается, но я не настолько уверен, поэтому мне трудно обойти эту проблему. Я попытался выпустить новый выходной буфер, прежде чем скрипт войдет в новую фазу завершения, потому что я думал, что это вызовет это. Но этого не произошло.

Solutions Collecting From Web of "Предотвращение исключений без стековых фреймов с обработчиками исключений ошибок и выключения"

Ваша проблема указывает на то, что вы используете версию EOL ( конец жизни ) PHP (в частности, PHP <5.3.0), что означает, что она больше не поддерживается. Эта проблема возникает из-за того, что вы выбрали исключение, где нет рамки strack, и поэтому старый движок не знал, как правильно обрабатывать эти исключения.

Это может быть связано с несколькими причинами. Вот некоторые из наиболее распространенных из них:

  1. Вы выбрали исключение изнутри обработчика ошибок или обработчика исключений.
  2. Вы выбрали исключение из деструктора.
  3. Вы выбрали исключение изнутри обратного вызова (например, функцию обратного вызова буферизации вывода).

Вот пример, который демонстрирует вашу проблему при некоторых из этих обстоятельств …

 function myErrorHandler($errno, $errstr, $errfile, $errline) { throw new ErrorException($errstr, $errno, 0, $errfile, $errline); } function myExceptionHandler($exception) { echo "We got an exception with message: '{$exception->getMessage()}'"; } function myCallBack($contents) { trigger_error('ohnoes!'); // You can't throw an error from the output buffer callback function in older versions of PHP < 5.3 } class Foo { public function __destruct() { trigger_error('ohnoes!'); // You can't throw an error from a destructor in older versions of PHP < 5.3 } } set_error_handler('myErrorHandler'); set_exception_handler('myExceptionHandler'); 

Вышеупомянутый код заставит вас увидеть фатальную ошибку, описанную здесь …

 ob_start("myCallBack"); 

… и здесь…

 $foo = new foo; 

Эта проблема была исправлена ​​в PHP> = 5.3.0, поэтому вы не должны видеть эту проблему, если используете самую последнюю версию PHP.

Самое простое исправление – обновить свой PHP. Если это не вариант, вы должны учитывать эти факты, что нельзя исключать исключения, когда PHP не ожидает их броска (в функциях обратного вызова, обработчиках ошибок, обработчиках исключений и т. Д.), Которые на самом деле считаются обратные вызовы для PHP).

Другое дело, что вы не должны превращать каждую ошибку в исключение таким образом. Если то, что вы делаете, так как код, который я предоставил, демонстрирует (т.е. исключение исключения изнутри обработчика ошибок – таким образом, превращая каждую ошибку в исключение), тогда вы будете причинять себе большую боль и практически без выгоды. Ошибки PHP не предназначены для обработки. Они предназначены для информирования клиента о проблеме ( клиент, являющийся человеком, пишущим код PHP ), или потенциальной проблемой. Обработка самой ошибки не так проста, как превратить каждую ошибку в исключение и затем обработать это исключение, потому что не каждая ошибка должна быть исключительной. Например, ошибки уровня E_NOTICE не имеют места в обработке исключений. Они в основном используются, чтобы уведомить вас о возможной ошибке, а не о том, что с вашим кодом обязательно что-то нехорошо, и не говоря уже о том, что большинство из них не могут быть легко обработаны в коде кода пользователя (они в основном требуют повторного использования, факторинг самого кода). Я настоятельно рекомендую эту плохую практику .