`

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
分享到:
评论

相关推荐

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

    7. **错误处理与调试**:学习如何在 Yii 2.0 中设置和使用日志组件,以及如何进行代码调试。 8. **部署与维护**:了解如何配置服务器环境,进行项目部署,并进行日常的监控和维护。 这些知识点的掌握将有助于你开发...

    php yii源码分析

    Yii 的组件系统是其核心特性之一,允许开发者定义和管理可重用的代码块。在构造函数中,`registerCoreComponents` 方法会注册一系列核心组件,比如数据库访问的 `db` 组件,日志处理的 `log` 组件等。这些组件可以...

    yii2-settings:Yii2 设置组件

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

    yii2.0 标签组件

    Yii2.0标签组件的核心特性包括: 1. **动态生成**:该组件能够根据数据库中的标签数据动态生成标签云,使得标签的数量和频率可以根据实际内容变化。 2. **样式自定义**:开发者可以自定义每个标签的样式,如字体...

    Yii 2文件下载

    1. **yiisoft/yii2**: 框架的核心组件,包括MVC(模型-视图-控制器)架构、数据库访问层、缓存机制、身份验证和授权等。 2. **Composer配置文件**:用于管理依赖和自动加载类库。 3. **基础应用模板**:提供一个基本...

    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框架快速入门

    4. **加速开发**:通过使用如Yii这样的框架,开发者可以重用框架提供的类和方法,显著提升开发效率。 #### 三、深入理解Yii ##### 3.1 入口脚本 / Entry Script 入口脚本(通常为`index.php`),是Yii框架与外部...

    Yii框架执行流程及部分源码分析

    `CApplication`是Yii框架的核心类,负责管理应用的生命周期。构造函数中,它会执行以下操作: - 解析配置,创建组件实例。 - 加载组件的配置。 - 注册错误处理和异常处理机制。 - 初始化Yii的类自动加载器。 -...

    YII2框架代码

    YII2是YII框架的最新版本,基于组件设计,提供MVC(Model-View-Controller)架构模式,支持命令行接口,具有强大的缓存管理,以及优秀的性能优化机制。它采用了现代PHP最佳实践,如依赖注入、单元测试和自动化工作...

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

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

    yii刷单平台.zip

    Yii的核心组件包括请求处理、响应生成、URL管理等,这些都可以被开发者自定义或扩展。在刷单平台项目中,你可以看到如何配置和使用这些组件来实现特定功能,如任务管理、用户交互等。 4. 数据库操作: Yii提供...

    yii-1.1.13源码

    `yiisoft/yii/framework`是核心框架目录,包含基础类和核心组件,如CApplication、CController、CModel等。其他如` yiisoft/yii/framework/web`针对Web应用的组件,`yiisoft/yii/framework/db`用于数据库操作。 2. ...

    yii2elfinder:yii2elfinder

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

    Yii_PHP_框架分析

    `YiiBase::$_coreClasses` 存储了 Yii 内置核心类的文件路径,而其他自定义类则存储在 `YiiBase::$_classes` 数组中。`Yii::import()` 方法用于将类路径添加到 PHP 的包含路径中。 3. **CWebApplication 创建** 当...

    Yii Framework API手册

    Yii Framework API手册是针对开发者的一款详尽参考资料,它包含了Yii框架的所有核心组件、类库以及扩展的使用方法和接口信息。Yii是一个高性能、基于组件的PHP框架,用于开发Web 2.0应用。API(Application ...

    Yii_RedisCache

    Yii 提供了对 Redis 的原生支持,通过 `yii\redis\Cache` 类来实现。这个类实现了 `\yii\caching\Cache` 接口,提供了标准的缓存操作,如设置、获取、删除数据,以及检查缓存是否存在等。集成 Redis 需要在配置文件...

    yii-demo:Yii 框架扩展的演示

    在 "yii-demo" 中,你可以看到模型类(Model)处理数据逻辑,视图(View)负责渲染用户界面,而控制器(Controller)则协调模型和视图之间的交互。 2. **组件系统**:Yii 提供了强大的组件化设计,允许开发者自定义...

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

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

    yii2-curl:yii2框架的cURL包装器

    1. **组件化**:`yii2-curl`基于Yii2的组件模式构建,这意味着你可以像使用其他任何Yii2组件一样配置、依赖注入和管理它。这简化了在项目中的集成和配置过程。 2. **配置友好**:通过Yii2的配置系统,可以方便地...

Global site tag (gtag.js) - Google Analytics