【问题标题】:Fatal error handling in YiiYii 中的致命错误处理
【发布时间】:2013-08-13 05:35:06
【问题描述】:

有没有办法在基于 Yii 框架的项目中通过电子邮件发送/记录 php 致命错误?

例如,可以将 Yii 配置为通过电子邮件发送“未定义变量”错误,但致命错误只能由单独的、未集成到框架代码中的不理想的代码来监控。

【问题讨论】:

    标签: php logging error-handling yii fatal-error


    【解决方案1】:

    在 php 中可以使用register_shutdown_function() 函数拦截致命错误。

    首先,让我们添加“早期”fatalparse 错误处理程序。它应该进入 index.php。 这段代码的目的是捕捉那些在控制器启动之前可能发生的错误。由于我们正在捕获应用程序启动期间可能发生的错误,因此最好使用简单的 php,而不依赖任何外部库:

    // Early fatal errors handler, it will be replaced by a full featured one in Controller class
    // (given it does not have any parse or fatal errors of its own)
    function earlyFatalErrorHandler($unregister = false)
    {
        // Functionality for "unregistering" shutdown function
        static $unregistered;
        if ($unregister) $unregistered = true;
        if ($unregistered) return;
    
        // 1. error_get_last() returns NULL if error handled via set_error_handler
        // 2. error_get_last() returns error even if error_reporting level less then error
        $error = error_get_last();
    
        // Fatal errors
        $errorsToHandle = E_ERROR | E_PARSE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING;
    
        if ((!defined('APP_PRODUCTION_MODE') || APP_PRODUCTION_MODE) && !is_null($error) && ($error['type'] & $errorsToHandle))
        {
            $message = 'FATAL ERROR: ' . $error['message'];
            if (!empty($error['file'])) $message .= ' (' . $error['file'] . ' :' . $error['line']. ')';
    
            mail('errors@YOURDOMAIN.COM', $message, print_r($error, 1));
    
            // Tell customer that you are aware of the issue and will take care of things
            // echo "Apocalypse now!!!"; 
        }
    }
    
    register_shutdown_function('earlyFatalErrorHandler');
    

    在这个阶段,我们仍然没有使用 Yii 错误处理程序或日志记录。首先,我们需要注册另一个关闭函数,它是我们基本控制器的一部分,并且可以使用 Yii 框架提供的标准错误处理和错误日志记录(这个想法的功劳和大部分代码转到vitalets@http://habrahabr.ru/post/136138/

    请注意,只要不是实际控制器文件中的解析错误,而是模型、帮助程序、视图等外部文件中的解析错误,此函数就会通知解析错误。如果解析错误在控制器中,早期处理程序将处理它。

    此外,此功能允许呈现更好的错误页面,而不是转储致命错误文本或显示空白屏幕(如果 display_errors 关闭)。

    /**
     * Controller is the customized base controller class.
     * All controller classes for this application should extend from this base class.
     */
    class Controller extends CController
    {
        // ...
    
        public function init()
        {
            register_shutdown_function(array($this, 'onShutdownHandler'));
            earlyFatalErrorHandler(true); // Unregister early hanlder
        }
    
        public function onShutdownHandler()
        {
            // 1. error_get_last() returns NULL if error handled via set_error_handler
            // 2. error_get_last() returns error even if error_reporting level less then error
            $error = error_get_last();
    
            // Fatal errors
            $errorsToHandle = E_ERROR | E_PARSE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING;
    
            if (!is_null($error) && ($error['type'] & $errorsToHandle))
            {
                // It's better to set errorAction = null to use system view "error.php" instead of
                // run another controller/action (less possibility of additional errors)
                Yii::app()->errorHandler->errorAction = null;
    
                $message = 'FATAL ERROR: ' . $error['message'];
                if (!empty($error['file'])) $message .= ' (' . $error['file'] . ' :' . $error['line']. ')';
    
                // Force log & flush as logs were already processed as the error is fatal
                Yii::log($message, CLogger::LEVEL_ERROR, 'php');
                Yii::getLogger()->flush(true);
    
                // Pass the error to Yii error handler (standard or a custom handler you may be using)
                Yii::app()->handleError($error['type'], 'Fatal error: ' . $error['message'], $error['file'], $error['line']);
            }
        }
    
        // ...
    }
    

    【讨论】:

      猜你喜欢
      • 2011-04-19
      • 1970-01-01
      • 2013-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-23
      • 2013-11-24
      相关资源
      最近更新 更多