Yii web程序入口(3)

来至:http://luchuan.iteye.com/blog/896886

本文分析前两篇文章用到的一些函数。

 

上一篇提到在preloadComponents的时候会调用getComponent,我们来看一下getComponent的细节:

 

Yii_PATH/base/CModule.php

Php代码   收藏代码
  1.     //第二个参数标识如果是空则创建之,默认为true  
  2.     public function getComponent($id,$createIfNull=true)  
  3.     {  
  4.         if(isset($this->_components[$id]))  
  5.             return $this->_components[$id];          
  6.         //_componentConfig是在configure方法中由setComponents中已经保存的变量  
  7.         else if(isset($this->_componentConfig[$id]) && $createIfNull)  
  8.         {  
  9.             $config=$this->_componentConfig[$id];  
  10.             unset($this->_componentConfig[$id]);   
  11.             //如果没有设置enable参数或者enable参数为true  
  12.             if(!isset($config['enabled']) || $config['enabled'])  
  13.             {   
  14.                 Yii::trace("Loading \"$id\" application component",'system.web.CModule');  
  15.                 unset($config['enabled']);   
  16.                 //创建组件,并完成初始化  
  17.                 $component=Yii::createComponent($config);  
  18.                 $component->init();  
  19.                 return $this->_components[$id]=$component;  
  20.             }  
  21.         }  
  22.     }  

 

下面是Yii::createComponent的实现:

Php代码   收藏代码
  1.     public static function createComponent($config)  
  2.     {  
  3.   
  4.         //如果配置项内容是一个字符串,则它是类名,如果是数组,那么数组的class成员是类名  
  5.         if(is_string($config))  
  6.         {  
  7.             $type=$config;  
  8.             $config=array();  
  9.         }  
  10.         else if(isset($config['class']))  
  11.         {  
  12.             $type=$config['class'];  
  13.             unset($config['class']);  
  14.         }  
  15.         else  
  16.             throw new CException(Yii::t('yii','Object configuration must be an array containing a "class" element.'));    
  17.         //如果类不存在,则使用import来引入,而不是用autoload  
  18.         if(!class_exists($type,false))  
  19.             $type=Yii::import($type,true);    
  20.   
  21.         //创建组件时,可以带更多的初始值进行初始化  
  22.         if(($n=func_num_args())>1)  
  23.         {  
  24.             $args=func_get_args();  
  25.             if($n===2)  
  26.                 $object=new $type($args[1]);  
  27.             else if($n===3)  
  28.                 $object=new $type($args[1],$args[2]);  
  29.             else if($n===4)  
  30.                 $object=new $type($args[1],$args[2],$args[3]);  
  31.             else  
  32.             {  
  33.                 unset($args[0]);  
  34.                 $class=new ReflectionClass($type);  
  35.                 // Note: ReflectionClass::newInstanceArgs() is available for PHP 5.1.3+  
  36.                 // $object=$class->newInstanceArgs($args);  
  37.                 //如果参数大于4个,那么调用newInstance方法来进行初始化  
  38.                 $object=call_user_func_array(array($class,'newInstance'),$args);  
  39.             }  
  40.         }  
  41.         else  
  42.             $object=new $type;    
  43.   
  44.         //将配置中的配置项赋值给组件的成员  
  45.         foreach($config as $key=>$value)  
  46.             $object->$key=$value;  
  47.   
  48.         return $object;  

 

=========================================================================

 

我们再来看看errorhandler和exceptionhandler:

 

Yii_PATH/base/CApplication.php

Php代码   收藏代码
  1.     public function handleError($code,$message,$file,$line)  
  2.     {  
  3.         if($code & error_reporting())  
  4.         {  
  5.             // disable error capturing to avoid recursive errors  
  6.             //恢复原错误handler(内建的错误handler),避免本函数触发错误handler,从而递归调用  
  7.             restore_error_handler();  
  8.             restore_exception_handler();  
  9.   
  10.             $log="$message ($file:$line)";  
  11.             if(isset($_SERVER['REQUEST_URI']))  
  12.                 $log.=' REQUEST_URI='.$_SERVER['REQUEST_URI'];  
  13.             Yii::log($log,CLogger::LEVEL_ERROR,'php');  
  14.   
  15.             try  
  16.             {    
  17.    
  18.                 //使用一个error事件类来触发error事件,然后显示log信息,这里暂不分析  
  19.                 $event=new CErrorEvent($this,$code,$message,$file,$line);  
  20.                 $this->onError($event);  
  21.                 if(!$event->handled)  
  22.                 {  
  23.                     // try an error handler  
  24.                     if(($handler=$this->getErrorHandler())!==null)  
  25.                         $handler->handle($event);  
  26.                     else  
  27.                         $this->displayError($code,$message,$file,$line);  
  28.                 }  
  29.             }  
  30.             catch(Exception $e)  
  31.             {  
  32.                 $this->displayException($e);  
  33.             }  
  34.             $this->end(1);  
  35.         }  
  36.     }  

dispalyError代码如下:

Php代码   收藏代码
  1. public function displayError($code,$message,$file,$line)                        
  2. {             
  3.     //如果是调试,打印调用栈,否则不打印  
  4.     if(YII_DEBUG)  
  5.     {             
  6.         echo "<h1>PHP Error [$code]</h1>\n";  
  7.         echo "<p>$message ($file:$line)</p>\n";  
  8.         echo '<pre>';  
  9.         debug_print_backtrace();  
  10.         echo '</pre>';                                                          
  11.     }                 
  12.     else  
  13.     {                     
  14.         echo "<h1>PHP Error [$code]</h1>\n";                                    
  15.         echo "<p>$message</p>\n";                                               
  16.     }         
  17. }        

 

 

参考:

Php手册代码   收藏代码
  1. 设 定了error hanlder之后,某些级别的错误是不会触发设置的函数的,例如:E_ERROR(运行期错误,如内存分配错误),E_PARSE(解 释错误,即语法),E_CORE_ERROR(在PHP内核startup阶段发生的错误),E_CORE_WARNING(在PHP内核startup 阶段发生的warning),E_COMPILE_ERROR(编译错误,zend引擎生成),E_COMPILE_WARNING(编译 warning,zend引擎生成)  
  2.   
  3. 关于startup和zend引擎请参考php内核方面的资料  

 

handleException与Error相似:

Php代码   收藏代码
  1.     public function handleException($exception)  
  2.     {  
  3.         // disable error capturing to avoid recursive errors  
  4.         restore_error_handler();  
  5.         restore_exception_handler();  
  6.   
  7.         $category='exception.'.get_class($exception);  
  8.         //如果是Http异常,获取状态码  
  9.         if($exception instanceof CHttpException)  
  10.             $category.='.'.$exception->statusCode;  
  11.         $message=(string)$exception;  
  12.         if(isset($_SERVER['REQUEST_URI']))  
  13.             $message.=' REQUEST_URI='.$_SERVER['REQUEST_URI'];  
  14.         Yii::log($message,CLogger::LEVEL_ERROR,$category);  
  15.   
  16.   
  17.         //接下来同handleError  
  18.         try  
  19.         {  
  20.             $event=new CExceptionEvent($this,$exception);  
  21.             $this->onException($event);  
  22.             if(!$event->handled)  
  23.             {  
  24.                 // try an error handler  
  25.                 if(($handler=$this->getErrorHandler())!==null)  
  26.                     $handler->handle($event);  
  27.                 else  
  28.                     $this->displayException($exception);  
  29.             }  
  30.         }  
  31.         catch(Exception $e)  
  32.         {  
  33.             $this->displayException($e);  
  34.         }  
  35.         $this->end(1);  
  36.     }  

 

参考:

Php手册代码   收藏代码
  1. call_user_function可以传递儿女和内置的或者用户自定义的函数,除了语言结构如array(), echo(), empty(), eval(), exit(), isset(), list(), print(), unset() 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值