Хороший вопрос +1
После моего обсуждения с @mpw моего первого ответа провел некоторые исследования и тесты после хорошей точки в направлении. Я частично неправильно понял это в первый раз.
Добавлю немного кода для прояснения, чтобы другие лучше поняли проблему.
Записка перед взлетом
У меня никогда не было таких проблем, пока это не появилось. Разрабатывая в Magento с включенным режимом разработчика, я даже и секунды не об этом думаю. Так что каждый раз, когда я пукну , он будет отображаться и будет исправлен соответствующим образом.
Проблема с объяснением образца
Ваше высказывание о фатальных ошибках будет зарегистрировано (если включено), и код продолжится как обычно, потому что ни одна ошибка не выдана, mageCoreErrorHandler
или программа будет exit
.
Первый обработчик ошибок Magento для неуловимых ошибок app/code/core/Mage/Core/functions.php
/**
* Custom error handler
*
* @param integer $errno
* @param string $errstr
* @param string $errfile
* @param integer $errline
*/
function mageCoreErrorHandler($errno, $errstr, $errfile, $errline){
/**
* Some internal logic here for building the error message
*/
$errorMessage .= ": {$errstr} in {$errfile} on line {$errline}";
if (Mage::getIsDeveloperMode()) {
throw new Exception($errorMessage);
} else {
Mage::log($errorMessage, Zend_Log::ERR);
}
}
Как видите, в режиме разработчика он скажет что-то полезное, выдает ошибку. При выключении он будет регистрироваться (если включен) и продолжаться.
Доказательство
мой testfile.php
require 'app/Mage.php';
Mage::app('admin')->setUseSessionInUrl(false);
// Test function which expect Customer_Model_Customer
function test(Customer_Model_Customer $customer)
{
var_dump('Do not show me because ' . get_class($customer) . ' is not a customer.');
}
// Enabled developer mode
Mage::setIsDeveloperMode(true);
// Put a var in here
$noGood = Mage::app();
// Make some context
var_dump('hello');
try {
// Call test function with a not accepted var
test($noGood);
// Tell if we get here
var_dump('And we are here!');
} catch (Exception $e) {
var_dump('You should die, because I am doing something which I should not do');
}
Результат
Режим разработчика включен. Правильный результат
string(5) "hello"
string(66) "You should die, because I am doing something which I should not do"
Режим разработчика отключен, неверный результат
string(5) "hello"
string(61) "Do not show me because Mage_Core_Model_App is not a customer."
string(16) "And we are here!"
Таким образом, он в конечном итоге пропустит ошибку и перейдет к следующей строке кода. Может быть, с еще более странными результатами. (как указывает @mpw)
Вывод
Это может случиться так, что кто - то развивается таким образом , что ошибки будут идти незамеченными , и это будет в конечном итоге привести к неожиданным результатам.
Конечно, при профессиональном развитии. Ошибки будут быть замечены и внимание будет оплачено. Способ предотвратить это в Magento - всегда включать режим разработчика в среде разработчика / тестирования.
ИМХО, это никогда не должно доходить до этой точки обсуждения, где проверка переменной во второй раз (по крайней мере, так я бы это описал) - это путь. Код должен быть протестирован перед выпуском в производственную среду. Это не должно быть необходимо.
Второстепенные мысли
Может быть, Magento должен остановиться после фатальной ошибки. Или создайте отчет и покажите его посетителю. Таким образом, следующие строки кода никогда не будут выполнены, и все будет замечено.
Хороший вопрос. Я думаю, что это общая проблема
E_RECOVERABLE_ERROR
в PHP.В вашем вопросе есть обработчик исключений, а не обработчик ошибок. Обработчик ошибок вызывает реальную проблему, которую вы обсуждаете здесь, с обнаруживаемыми фатальными ошибками (
E_RECOVERABLE_ERROR
) .В PHP 7 и HHVM это уже решено.
С Magento хуже, потому что обработчик ошибок не работает с этим, начиная с класса ошибок PHP 5.2.
Более полезным видом обработки ошибок будет иметь дело с этим классом ошибок и превращать эти ошибки в ErrorException s. Пример (не мной, отсюда ):
Таким образом, в свете Magento обработчиком ошибок по умолчанию является глобальная функция
mageCoreErrorHandler
вapp/code/core/Mage/Core/functions.php
. Это получить зарегистрированный с помощью сMage::app()
помощьюinit()
метода в Mage_Core_Model_App (app/code/core/Mage/Core/Model/App.php
) (через защищенный_initEnvironment()
метод).Тогда достаточно наблюдателя,
controller_front_init_before
который регистрирует ваш собственный обработчик ошибок PHP сверху (обработчики ошибок в PHP являются наращиваемыми):ловимые фатальные ошибки затем превращаются в исключения, и вы можете обращаться с ними в своем собственном коде расширения, или они не будут обработаны и будут отображаться в журнале исключений (вместо того, чтобы ваш магазин запускал неверные типы, такие как текущее поведение, мертвые программы не ври ) В PHP 7 исключение, которое нужно искать, это не ErrorException, а TypeException (который является BaseException ) для теперь перехватываемых фатальных ошибок .
Все остальные ошибки передаются в обработчик ошибок Magento.
Примечание: я не пробовал это, это рецензия, но я знаю проблему, о которой вы спрашиваете, и анализ обработки ошибок был выполнен на 1.5.1.0 и проверен на 1.9.1.0 посредством анализа кода. Укладка обработчика ошибок должна работать. Я добавляю небольшой расширенный пример кода, который демонстрирует работу большинства частей.
Я еще не упаковал это как расширение magento, но оно должно быть прямым с modman. Я положу это на github тогда.
Приложение: Демонстрация ошибок обработчика
В следующем примере кода ( онлайн-демонстрация ) демонстрируется укладка обработчиков ошибок и создание исключений при обнаруживаемой фатальной ошибке :
Выход программы
источник
Он уже обработан по умолчанию PHP, добавив
(Exception $e)
в определение параметра функции.Вы не можете передать в эту функцию что-либо еще, кроме Исключения или расширения Исключения.
источник
mageCoreErrorHandler
функцию. Ошибка, вызванная неправильными параметрами, будет обработана и подавлена в режиме не для разработчиков, а такжеException
в режиме разработчика.mageCoreErrorHandler
быть уверен, что посетители не получат сообщение об ошибке. Вы можете создать свое собственное,try{}catch(){}
чтобы захватить их сами, и если вы не можете передать их.