yii2框架的錯誤處理
阿新 • • 發佈:2019-02-17
一直對框架的錯誤處理有些疑惑,為什麼我的程式一旦出現問題,就會自動打印出錯誤呢?他是怎麼監聽的?在哪裡用的try catch嗎??
這是我一直以來的困惑,可現在知道了,原來,原來php有自己的API當程式出現問題時,可以自動呼叫指定函式,進行處理YII2啟動的時候,會自動註冊錯誤處理函式set_error_handler
在components中是這樣定義的:
而site/error則是在siteController中的actions中定義的!!!
這樣,error的定義是在yii\web\errorAction當中,也就是說,我們需要看這個類的定義ErrorHandler 在啟動的時候,呼叫了register,其定義如下:
呼叫了handlerError成員函式
這樣我們就能得到完整的錯誤資訊的呼叫情況了
public function __construct($config = []) { Yii::$app = $this; static::setInstance($this); $this->state = self::STATE_BEGIN; $this->preInit($config); $this->registerErrorHandler($config); Component::__construct($config); }
對,就是這個registerErrorHandler,其定義如下:
protected function registerErrorHandler(&$config) { if (YII_ENABLE_ERROR_HANDLER) { if (!isset($config['components']['errorHandler']['class'])) { echo "Error: no errorHandler component is configured.\n"; exit(1); } $this->set('errorHandler', $config['components']['errorHandler']); unset($config['components']['errorHandler']); $this->getErrorHandler()->register(); } }
在components中是這樣定義的:
'errorHandler' => [
'errorAction' => 'site/error',
],
而site/error則是在siteController中的actions中定義的!!!
/** * @inheritdoc */ public function actions() { return [ 'error' => [ 'class' => 'yii\web\ErrorAction', ], 'captcha' => [ 'class' => 'yii\captcha\CaptchaAction', 'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null, ], ]; }
這樣,error的定義是在yii\web\errorAction當中,也就是說,我們需要看這個類的定義ErrorHandler 在啟動的時候,呼叫了register,其定義如下:
public function register()
{
ini_set('display_errors', false);
set_exception_handler([$this, 'handleException']);
if (defined('HHVM_VERSION')) {
set_error_handler([$this, 'handleHhvmError']);
} else {
set_error_handler([$this, 'handleError']);
}
if ($this->memoryReserveSize > 0) {
$this->_memoryReserve = str_repeat('x', $this->memoryReserveSize);
}
register_shutdown_function([$this, 'handleFatalError']);
}
呼叫了handlerError成員函式
public function handleError($code, $message, $file, $line)
{
if (error_reporting() & $code) {
// load ErrorException manually here because autoloading them will not work
// when error occurs while autoloading a class
if (!class_exists('yii\\base\\ErrorException', false)) {
require_once(__DIR__ . '/ErrorException.php');
}
$exception = new ErrorException($message, $code, $code, $file, $line);
// in case error appeared in __toString method we can't throw any exception
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);//得到呼叫棧陣列
array_shift($trace);
foreach ($trace as $frame) {
if ($frame['function'] === '__toString') {
$this->handleException($exception);
if (defined('HHVM_VERSION')) {
flush();
}
exit(1);
}
}
throw $exception;
}
return false;
}
這樣我們就能得到完整的錯誤資訊的呼叫情況了