В течение недели у меня была небольшая проблема. Сообщение об ошибке перед этим:
[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
Это в основном моя проблема. Есть ли простой способ предотвратить получение этих ошибок? Я несколько знаю, почему ошибка дается, но я не настолько уверен, поэтому мне трудно обойти эту проблему. Я попытался выпустить новый выходной буфер, прежде чем скрипт войдет в новую фазу завершения, потому что я думал, что это вызовет это. Но этого не произошло.
Ваша проблема указывает на то, что вы используете версию EOL ( конец жизни ) PHP (в частности, PHP <5.3.0), что означает, что она больше не поддерживается. Эта проблема возникает из-за того, что вы выбрали исключение, где нет рамки strack, и поэтому старый движок не знал, как правильно обрабатывать эти исключения.
Это может быть связано с несколькими причинами. Вот некоторые из наиболее распространенных из них:
Вот пример, который демонстрирует вашу проблему при некоторых из этих обстоятельств …
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 не имеют места в обработке исключений. Они в основном используются, чтобы уведомить вас о возможной ошибке, а не о том, что с вашим кодом обязательно что-то нехорошо, и не говоря уже о том, что большинство из них не могут быть легко обработаны в коде кода пользователя (они в основном требуют повторного использования, факторинг самого кода). Я настоятельно рекомендую эту плохую практику .