좋은 질문. E_RECOVERABLE_ERROR
PHP에서 일반적인 문제라고 생각합니다 .
귀하의 질문에있는 것은 오류 처리기가 아닌 예외 처리기입니다. 오류 처리기와 여기에 논의 실제 문제를 일으키는 잡을 치명적인 오류 ( E_RECOVERABLE_ERROR
) .
PHP 7과 HHVM은 이미 해결되었습니다.
PHP 5.2 오류 클래스 이후로 오류 처리기가이 문제를 처리하지 않기 때문에 Magento가 더 나쁩니다.
보다 유용한 종류의 오류 처리는이 오류 클래스를 처리하고 이러한 오류를 ErrorException 으로 바꾸는 것 입니다. 예 (나가 아니라 여기에서 ) :
set_error_handler(function($errno, $errstr, $errfile, $errline) {
if ($errno === E_RECOVERABLE_ERROR) {
throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
}
return false;
});
따라서 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()
방법).
PHP 오류 처리기를 맨 위에 등록 하는 관찰자controller_front_init_before
는 충분해야합니다 (PHP의 오류 처리기는 스택 가능).
$previous = set_error_handler(function($errno, $errstr, $errfile, $errline) use (&$previous) {
if ($errno === E_RECOVERABLE_ERROR) {
throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
}
if ($previous) {
return call_user_func($previous, $errno, $errstr, $errfile, $errline);
}
return false;
});
잡을 치명적인 오류는 다음 예외로 켜져 있고 당신은 당신의 자신의 확장 코드에서 처리 할 수 또는 그들이 포착되지 않은 있습니다 대신 현재 동작이처럼 잘못된 유형에 대한 당신의 상점 실행 가가있는의 (예외 로그에 표시됩니다 죽은 프로그램 거짓말하지 마십시오 ). PHP 7 찾을 수있는 예외가 아니다 ErrorException 다음하지만 TypeException (A입니다 BaseException 지금의 경우) 잡을 치명적인 오류 .
다른 모든 오류는 Magento의 오류 처리기로 전달됩니다.
참고 : 나는 이것을 시도하지 않았지만, 그것은 기록이지만 당신이 묻는 문제를 알고 있으며 오류 처리 분석은 1.5.1.0에 대해 수행되었으며 코드 분석을 통해 1.9.1.0에 대해 검증되었습니다. 오류 처리기 스태킹이 작동해야합니다. 대부분의 부분이 작동하는 것을 보여주는 약간의 확장 된 예제 코드를 추가합니다.
나는 이것을 magento 확장으로 아직 패키지하지 않았지만 modman을 사용하여 간단해야합니다. 그런 다음 github에 넣겠습니다.
부록 : 오류 처리기 데모
다음 코드 예제 ( 온라인 데모 )는 오류 처리기의 스택 및 캐치 가능한 치명적 오류 에 대한 예외 발생을 보여줍니다 .
<?php
/**
* error handler demonstration
*
* stackable error handle with previous call and catchable error exceptions
*
* @author hakre <http://hakre.wordpress.com>
* @link /magento//a/64972/4115
*/
set_error_handler(function() {
$args = func_get_args();
var_dump("me is the previous error handler", $args);
});
$previous = set_error_handler(function($errno, $errstr, $errfile, $errline) use (&$previous) {
if ($errno === E_RECOVERABLE_ERROR) {
throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
}
if ($previous) {
return call_user_func($previous, $errno, $errstr, $errfile, $errline);
}
return false;
});
$test = function(callable $test) {};
$a = $undefined; // provoke little warning
$test(new stdClass); // provoke catchable fatal error
프로그램 출력
string(32) "me is the previous error handler"
array(4) {
[0]=>
int(8)
[1]=>
string(29) "Undefined variable: undefined"
[2]=>
string(45) "/tmp/execpad-0eca072b619d/source-0eca072b619d"
[3]=>
int(28)
}
Fatal error: Uncaught exception 'ErrorException' with message 'Argument 1 passed to {closure}() must be callable, object given, called in /tmp/execpad-0eca072b619d/source-0eca072b619d on line 30 and defined' in /tmp/execpad-0eca072b619d/source-0eca072b619d:26
Stack trace:
#0 /tmp/execpad-0eca072b619d/source-0eca072b619d(26): {closure}(4096, 'Argument 1 pass...', '/tmp/execpad-0e...', 26, Array)
#1 /tmp/execpad-0eca072b619d/source-0eca072b619d(30): {closure}(Object(stdClass))
#2 {main}
thrown in /tmp/execpad-0eca072b619d/source-0eca072b619d on line 26