1.错误处理
发生错误后引发 handleError() 函数处理:
public function handleError($code,$message,$file,$line)
{
if($code & error_reporting())
{
// disable error capturing to avoid recursive errors
restore_error_handler();
restore_exception_handler();
//restore_error_handler,
restore_exception_handler两个函数,如果没有这两个函数的调用,那么在后续的错误处理过程中,
当再次产生异常或是错误时,又会调用CApplication:: handleError ,从而可能造成死循环,
故Yii在此处临时禁止了使用CApplication:: handleError 接管后续的错误和异常(使用php默认的错误处理机制),
这就保证了不会因之产生循环调用。
$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);
//此时将产生一个CErrorEvent(并包含$code,$message,$file,$line几项关键参数),
传递给CErrorHandler组件进行处理。具体是交给CErrorHandler::handleError处理之
。这个流程主要是将错误相关信息进行整理,并以合适的方式进行显示。
$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);
}
}
}
2.异常处理
3.使用一个动作来处理错误