`

Yii分析11:Yii核心组件之错误处理类CErrorHandler

 
阅读更多

 

类如其名,CErrorHandler在Yii中主要的功能就是处理未捕获的错误和异常,它使用两种视图:开发视图和生产视图,以区分不同的部署环境。

与CDbConnection一样,CErrorHandler也是CApplication的一个核心组件,在创建应用程序时,作为应用程序的一个内部示例自动初始化,CErrorHandler没有定义自己的init函数,因此使用的是父类的初始化。

在创建应用程序实例时,会调用PHP的错误和异常注册函数来指定使用系统自定义的错误处理类来处理错误和异常:

CApplication:

abstract class CApplication extends CModule
	public function __construct($config=null)
	{
		……
		//初始化系统处理函数
		$this->initSystemHandlers();
		$this->registerCoreComponents();
		……
	}
	protected function initSystemHandlers()
	{
		if(YII_ENABLE_EXCEPTION_HANDLER)
			//设置异常处理函数
			set_exception_handler(array($this,'handleException'));
		if(YII_ENABLE_ERROR_HANDLER)
			//设置错误处理函数
			set_error_handler(array($this,'handleError'),error_reporting());
	}
	//错误处理函数
	public function handleError($code,$message,$file,$line)
	{
		if($code & error_reporting())
		{
			// disable error capturing to avoid recursive errors
			restore_error_handler();
			restore_exception_handler();

			$log="$message ($file:$line)\nStack trace:\n";
			$trace=debug_backtrace();
			// skip the first 3 stacks as they do not tell the error position
			if(count($trace)>3)
				$trace=array_slice($trace,3);
			foreach($trace as $i=>$t)
			{
				if(!isset($t['file']))
					$t['file']='unknown';
				if(!isset($t['line']))
					$t['line']=0;
				if(!isset($t['function']))
					$t['function']='unknown';
				$log.="#$i {$t['file']}({$t['line']}): ";
				if(isset($t['object']) && is_object($t['object']))
					$log.=get_class($t['object']).'->';
				$log.="{$t['function']}()\n";
			}
			if(isset($_SERVER['REQUEST_URI']))
				$log.='REQUEST_URI='.$_SERVER['REQUEST_URI'];
			Yii::log($log,CLogger::LEVEL_ERROR,'php');

			try
			{
				Yii::import('CErrorEvent',true);
				$event=new CErrorEvent($this,$code,$message,$file,$line);
				$this->onError($event);
				if(!$event->handled)
				{
					// try an error handler
					//如果注册了错误处理类,使用错误处理类来处理,否则直接显示错误
					if(($handler=$this->getErrorHandler())!==null)
						$handler->handle($event);
					else
						$this->displayError($code,$message,$file,$line);
				}
			}
			catch(Exception $e)
			{
				$this->displayException($e);
			}

			try
			{
				$this->end(1);
			}
			catch(Exception $e)
			{
				// use the most primitive way to log error
				$msg = get_class($e).': '.$e->getMessage().' ('.$e->getFile().':'.$e->getLine().")\n";
				$msg .= $e->getTraceAsString()."\n";
				$msg .= "Previous error:\n";
				$msg .= $log."\n";
				$msg .= '$_SERVER='.var_export($_SERVER,true);
				error_log($msg);
				exit(1);
			}
		}
	}
	//异常处理函数
	public function handleException($exception)
	{
		// disable error capturing to avoid recursive errors
		restore_error_handler();
		restore_exception_handler();

		$category='exception.'.get_class($exception);
		if($exception instanceof CHttpException)
			$category.='.'.$exception->statusCode;
		// php <5.2 doesn't support string conversion auto-magically
		$message=$exception->__toString();
		if(isset($_SERVER['REQUEST_URI']))
			$message.=' REQUEST_URI='.$_SERVER['REQUEST_URI'];
		Yii::log($message,CLogger::LEVEL_ERROR,$category);

		try
		{
			$event=new CExceptionEvent($this,$exception);
			$this->onException($event);
			if(!$event->handled)
			{
				// try an error handler
				if(($handler=$this->getErrorHandler())!==null)
					$handler->handle($event);
				else
					$this->displayException($exception);
			}
		}
		catch(Exception $e)
		{
			$this->displayException($e);
		}

		try
		{
			$this->end(1);
		}
		catch(Exception $e)
		{
			// use the most primitive way to log error
			$msg = get_class($e).': '.$e->getMessage().' ('.$e->getFile().':'.$e->getLine().")\n";
			$msg .= $e->getTraceAsString()."\n";
			$msg .= "Previous exception:\n";
			$msg .= get_class($exception).': '.$exception->getMessage().' ('.$exception->getFile().':'.$exception->getLine().")\n";
			$msg .= $exception->getTraceAsString()."\n";
			$msg .= '$_SERVER='.var_export($_SERVER,true);
			error_log($msg);
			exit(1);
		}
	}
 
    总的来说,错误处理主要是注册自己的错误处理类和触发错误事件,以可视化的形式展示错误和异常。
1
0
分享到:
评论

相关推荐

    yii2-settings:Yii2 设置组件

    Yii2 设置组件 安装 安装此扩展的首选方法是通过 。 要么跑 php composer.phar require --prefer-dist pendalf89/yii2-settings "*" 或添加 "pendalf89/yii2-settings": "*" 到composer.json文件的 require 部分...

    yii-robokassa:用于与 Robokassa 支付服务的 api 配合使用的 Yii 组件

    用于与支付的 api 配合使用的 Yii 组件 安装 从这个 github 存储库下载 yii-robokassa: cd protected/components git clone https://github.com/ladamalina/yii-robokassa.git 在 protected/config/main.php 中...

    Yii 2.0进阶版 高级组件 优化京东平台

    Yii 2.0进阶版 高级组件 优化京东平台 包括前后台源代码,使用php 实现数据库mysql

    yii2-swoole:完整的解决方案,使yii2-framework与协程在swoole上运行

    此插件基于 swoole (v2.0) 底层实现的协程,改造 Yii2 的核心代码,使开发者无感知,以及在不改动业务代码的情况下,用上 swoole 的异步IO能力。 特性 协程 MySQL 客户端、连接池,支持主从、事务。 协程 Redis ...

    yii-passport:使Laravel Passport与Yii一起工作

    Yii护照 安装 :light_bulb: 这是展示如何安装软件包的好地方,请参见下文: 跑步 $ composer require inquid/yii-passport 用法 :light_bulb: 这是显示一些用法示例的好地方! 变更日志 请看看 。 贡献 请看看 。...

    yii2elfinder:yii2elfinder

    yii2elfinder 感谢: : 感谢:zybodya 提供当前 yii 版本 yii2elfinder 介绍:旧版本无法使用,因为它完全不适用于最新的jquery版本! 所以除了行动,我不得不改变一切;) 这个扩展允许你将 ElFinder 文件管理...

    yii2-beanstalk, Yii2 beanstalk web和控制台组件.zip

    yii2-beanstalk, Yii2 beanstalk web和控制台组件 yii2-beanstalkYii2 beanstalkd web和控制台组件,它是 pda/pheanstalk服务器顶部的一个接口。 感谢 Paul Annesley 完成这项工作。:如何使用?插件安装与 Composer...

    yii2-curl:用于 curl 的 Yii2 组件

    php composer.phar require --prefer-dist peterfrench/yii2-curl " * " 一旦 composer 安装了扩展,在您的配置文件中包含该组件。 'curl' =&gt; ['class' =&gt; 'peterfrench\curl\Curl' ,'options' =&gt; [/* curl options...

    yii-qa:基于Yii2实现的问答系统

    Yii-QA简介(此项目目前已不再维护)感谢选择Yii-QA,基于框架基础实现的问答程序。 #意识到目前的急性时间有限,无法管理太多的额外项目,我准备合并现有手上的项目,集成在一个项目中,感谢支持!!!!!!!请关注:...

    yii-simplepie:Yii1.* 的 RSS 解析扩展

    yii-simplepie yii-simplepie 是用于解析 rss 提要的 yii 扩展: 简单派: simplepie 文档: 用法 在 yii 中安装扩展 下载所有文件并放入 yii 扩展文件夹,然后在 config/main.php 中添加以下代码 'simplepie' ...

    yii2-fullcalendar:Yii 2组件,可轻松实现全日历集成

    Yii2全日历组件 安装 安装此扩展的首选方法是通过 。 要安装,请运行 $ php composer.phar require edofre/yii2-fullcalendar "V1.0.11" 或添加 "edofre/yii2-fullcalendar": "V1.0.11" 到composer.json文件的...

    yii-ckeditor:简单的 Yii 框架 CKEditor 小部件

    Yii 框架的 CKEditor 小部件 简单的 Yii CKEditor 小部件。 CKEditor - 每个人的 WYSIWYG 编辑器。 小部件生成具有相同属性的 CHtml::activeTextArea。 使用 CKEditor 4+ 版本测试。 安装 将此小部件复制到扩展...

    Yii框架应用组件用法实例分析

    本文实例讲述了Yii框架应用组件用法。分享给大家供大家参考,具体如下: 应用组件 ¶ 应用主体是服务定位器, 它部署一组提供各种不同功能的 应用组件 来处理请求。 例如,urlManager组件负责处理网页请求路由到对应...

    yii2swoole让yii2运行在swoole上

    yii2 swoole:让yii2运行在swoole上 , 运行在swoole上的yii2是运行在php-fpm上yii2的5倍以上

    yii-fullcalendar:Arshaw 的 FullCalendar jQuery 插件的 Yii 扩展

    Arshaw 的 FullCalendar jQuery 插件的 Yii 扩展 作者:Alexey Samoylov ( )。 要求 PHP 5.4 Yii 1.x 例子 全局组件配置示例: 'components' =&gt; [ 'fullcalendar' =&gt; [ 'class' =&gt; 'ext.yii-fullcalendar....

    yii-seo:Yii PHP 框架的搜索引擎优化

    yii-seo Yii PHP 框架的搜索引擎优化。 用法 布局中 &lt;?php Yii::app()-&gt;controller-&gt;widget( 'vendor.crisu83.yii-seo.widgets.SeoHead', array( 'httpEquivs' =&gt; array( 'Content-Type' =&gt; 'text/html; ...

    yii2sly:jquery 狡猾

    yii2sly 这个扩展是惊人的 jquery 滑块“sly”的包装器,可以在这里找到: 请。 仔细查看所有插件选项,可以通过将它们添加到“clientOptions”参数来传递这些选项,如下所示。 可以在此处找到扩展的演示: 安装 ...

    yii2-schemadump:从现有数据库生成模式

    yii2-schemadump 从现有数据库生成模式。演示版要求PHP 7.3或更高版本Yii 2.x安装composer require --dev jamband/yii2-schemadump用法在config / console.php中添加以下内容: return [ . . . 'components' =&gt; [ . ...

    yii2-mailqueue, 用于 yii2 swiftmailer https的yii2的电子邮件队列组件.zip

    yii2-mailqueue, 用于 yii2 swiftmailer https的yii2的电子邮件队列组件 yii2-mailqueue适用于 yii2-swiftmailer的yii2的电子邮件队列组件安装安装这个扩展的首选方法是通过 composer插件。运行...

    yii2.0 标签组件

    yii2.0 tags标签组件下载。

Global site tag (gtag.js) - Google Analytics