Yii框架学习第二天-执行流程

我直的很懒,由于大概流程我已搞懂,我也懒得一步步分析了,转载吧。

6、$config 之 import  

 
其中 import 被传递给 CModule 的 setImport:  
   1.  public  function setImport( $aliases)  
   2. {  
   3.     foreach( $aliases  as  $alias)  
   4.     Yii::import( $alias);  
  5. }  

Yii::import( $alias)里的处理:  
   1.  public  static  function import( $alias, $forceInclude= false)  
   2. {  
   3.     //  先判断$alias是否存在于YiiBase::$_imports[] 中,已存在的直接return, 避免重复import。  
   4.     if( isset(self:: $_imports[ $alias]))  //  previously imported  
   5.      return self:: $_imports[ $alias];  
   6.  
   7.     //  $alias类已定义,记入$_imports[],直接返回  
   8.     if( class_exists( $alias, false))  
   9.      return self:: $_imports[ $alias]= $alias;  
  10.  
  11.     //  类似 urlManager 这样的已定义于$_coreClasses[]的类,或不含.的直接类名,记入$_imports[],直接返回  
  12.     if( isset(self:: $_coreClasses[ $alias]) || ( $pos= strrpos( $alias,'.'))=== false//  a simple class name  
  13.    {  
  14.     self:: $_imports[ $alias]= $alias;  
  15.      if( $forceInclude)  
  16.     {  
  17.       if( isset(self:: $_coreClasses[ $alias]))  //  a core class  
  18.        require(YII_PATH.self:: $_coreClasses[ $alias]);  
  19.       else 
  20.        require( $alias.'.php');  
  21.     }  
  22.      return  $alias;  
  23.    }  
  24.  
  25.     //  产生一个变量 $className,为$alias最后一个.后面的部分  
  26.     //  这样的:'x.y.ClassNamer'  
  27.     //  $className不等于 '*', 并且ClassNamer类已定义的,      ClassNamer' 记入 $_imports[],直接返回  
  28.     if(( $className=( string) substr( $alias, $pos+1))!=='*' &&  class_exists( $className, false))  
  29.      return self:: $_imports[ $alias]= $className;  
  30. 
  31.     //  取得 $alias 里真实的路径部分并且路径有效  
  32.     if(( $path=self::getPathOfAlias( $alias))!== false)  
  33.    {  
  34.      //  $className!=='*',$className 记入 $_imports[]  
  35.      if( $className!=='*')  
  36.     {  
  37.      self:: $_imports[ $alias]= $className;  
  38.       if( $forceInclude)  
  39.        require( $path.'.php');  
  40.       else 
  41.       self:: $_classes[ $className]= $path.'.php';  
  42.       return  $className;  
  43.     }  
  44.      //  $alias是'system.web.*'这样的已*结尾的路径,将路径加到include_path中  
  45.      else  //  a directory  
  46.     {  
  47.       set_include_path( get_include_path().PATH_SEPARATOR. $path);  
  48.       return self:: $_imports[ $alias]= $path;  
  49.     }  
  50.    }  
  51.     else 
  52.      throw  new CException(Yii::t('yii','Alias "{alias}" is invalid. Make sure it points to an existing directory or file.',  
  53.       array('{alias}'=> $alias)));  
  54. } 

   


7. $config 之 components  

   
$config 数组里的  $components 被传递给CModule 的setComponents( $components)  
   1.  public  function setComponents( $components)  
   2. {  
   3.     foreach( $components  as  $id=> $component)  
   4.    {  
   5.      if( $component instanceof IApplicationComponent)  
   6.       $this->setComponent( $id, $component);  
   7.      else  if( isset( $this->_componentConfig[ $id]))  
   8.       $this->_componentConfig[ $id]=CMap::mergeArray( $this->_componentConfig[ $id], $component);  
  9.      else 
  10.       $this->_componentConfig[ $id]= $component;  
  11.    }  
  12. }  
$componen是IApplicationComponen的实例的时候,直接赋值:  
$this->setComponent( $id, $component),  
   1.  public  function setComponent( $id, $component)  
   2. {  
   3.     $this->_components[ $id]= $component;  
  4.     if(! $component->getIsInitialized())  
   5.      $component->init();  
   6. }  
如果 $id已存在于_componentConfig[]中(前面注册的coreComponent),将 $component 属性加进入。  
其他的component将component属性存入_componentConfig[]中。  
 
   
8$config 之 params 
    
这个很简单    
   1.  public  function setParams( $value)  
   2. {  
   3.     $params= $this->getParams();  
   4.     foreach( $value  as  $k=> $v)  
   5.      $params->add( $k, $v);  
   6. }  
configure 完毕!  

   

9. attachBehaviors  

   

$this->attachBehaviors( $this->behaviors);  
空的,没动作  
预创建组件对象  
   1.  $this->preloadComponents();  
   2.  
   3.  protected  function preloadComponents()  
   4. {  
   5.     foreach( $this->preload  as  $id)  
   6.      $this->getComponent( $id);  
   7. }  
getComponent() 判断_components[] 数组里是否有  $id的实例,如果没有,就根据_componentConfig[ $id]里的配置来创建组件对象,调用组件的init()方法,然后存入_components[ $id]中。  

10. init() 
 
this->init();  
函数内: $this->getRequest();  
创建了Reques 组件并初始化。  
   

11. run()  

   
   1.  public  function run()  
   2. {  
   3.     $this->onBeginRequest( new CEvent( $this));  
   4.     $this->processRequest();  
   5.     $this->onEndRequest( new CEvent( $this));  
   6. }  


三 大概过程  

application构造函数:  
1 设置当前运行实例  
2 获取配置参数  
3 设置basepath  
4 设置几个path;application,webroot ,ext  
5 preinit  
6 注册error、exception处理函数 initSystemHandlers  
7 加载核心组件 registerCoreComponents 包括webapplication的和application的  
8 设置配置文件 configure( $config)  
9 附加行为  $this->attachBehaviors( $this->behaviors);  
10处理加载config中的preload, // 通过getComponent分别加载并初始化 $this->preloadComponents();   
11 初始化init();  // 加载CHttpRequest组件 
 
run:  
1 处理onBeginRequest  
2 processRequest();真正处理请求  
3 处理onEndRequest  

webapplication->processRequest():  
1  如果配置文件设置了catchAllRequest ,  //  'catchAllRequest'=>array('site/error','p1'=>'1','p2'=>'2'),  
   则所有请求都跳转到这个controller/action这个route,并且设置 $_GET参数。        
2  分析url得到route,便于后面的控制器/动作创建     
3  执行runController 
       
runController:     
1 创建controller, createController(),创建失败,则抛出404错误  
2 得到controller对象和actionID  
3 控制器初始化   $controller->init();  
4 最后执行    $controller->run( $actionID); // 真正执行页面请求
  
控制器类  
CController:默认控制器在CWebApplication::defaultController定义('site'),可以在配置文件修改  
run():  
// 根据actionID创建action对象,这里生成的action对象分为定义在controller内联动作和自定义action,比如CViewAction  
   $action= $this->createAction( $actionID),如果创建动作失败,missingAction抛出404错误  
2 beforeControllerAction(beforeControllerAction定义在CWebApplication,有时也在module里面)为真,才执行runActionWithFilters;  
3 afterControllerAction    
runActionWithFilters( $action, $this->filters()):  
// 如果过滤器为空,直接运行runAction()  
2 执行过滤器链  
runAction():  
1 beforeAction()返回真,才执行  
2 执行 $action->runWithParams();注意:这里存在多态,每个action都可以实现这个方法, 因为CInlineAction自己实现了runWithParams()  
3 第2步骤为真,才执行afterAction( $action);  
动作类  默认动作在CController:: $defaultAction定义('index'),可以在CController的继承类重新定义  
runWithParams():  
1 分为2种情况,1种是内联动作,1种是通过控制器的actions方法定义的外联动作。  
2 内联动作 通过action+动作id作为动作处理函数  
3 外联动作 通过调用run()函数来实现  
4 如果动作方法参数个数大于0,执行runWithParamsInternal,否则直接执行动作方法。     
runWithParamsInternal();  
1 根据反射的方法对象得到方法的形参列表,从 控制器对象->getActionParams()得到实参,  
  如果实参有形参要求的参数,取其值,不然取形参默认值,否则,出错。  
2 调用动作方法   2种形式 1是action+动作id ,2是Caction的派生类(比如cviewaction)的run()  
3 执行控制器的CController->render方法; $controller->render( $view)  
控制器类  
CController:  
render();  
1 renderPartial();得到视图, // 先得到contact页面的view文件内容,注意是用include的形式,所以其中的$this是指siteControlerd对象,  
  这里调用了renderFile();  
2  然后 $output= $this->renderFile( $layoutFile, array('content'=> $output), true)  
   把view中的内容插入到布局页面layouts的column1.php,    'content'和layout的页面的 $content变量相关  
renderFile();  
1 如果程序没有定义viewrender,则执行controller->renderInternal();否则,执行 $renderer=Yii::app()->getViewRenderer())->renderFile(); 
view sourceprint?发生404错误  
errorHandler 在配置文件main中,'errorAction' => 'site/error',  

**********************************************************  

runActionWithFilters  
过滤:  
CFilterChain(继承CList,提供数字索引存取功能,遍历)::create( $this, $action, $filters)->run();  
首先创建过滤链,然后执行过滤  
CFilterChain::create( $controller, $action, $filters):  
$chain= new CFilterChain( $controller, $action);创建一个过滤链 $chain 
2 根据参数filters数组,遍历创建过滤器 $filter(字符串:通过CInlineFilter::create或者 数组:Yii::createComponent),  
  并且初始化 $filter::init,通过 $chain->add( $filter)添加到过滤链中,并且返回这个过滤链 $chain   
注意:如果是字符串,控制器类controller必须要有"filter"+过滤器名的方法。  
$chain::run();  
1 如果数字索引合法,得到 $filter,然后执行 $filter->filter( $this);  
 1.1  $filter->filter( $this):  
       1 执行动作的'filter'+过滤器名称的方法。 // 比如CController::filterAccessControl($filterChain);  
   1.1.1 CController::filterAccessControl( $filterChain):  
          1  $filter= new CAccessControlFilter; // 新建过滤器  
          2  $filter->setRules( $this->accessRules()); // 设置规则  
          3  $filter->filter( $filterChain)  ; // 执行过滤  
          4  $filter->preFilter( $filterChain)为真,继续执行 $filterChain->run();  
          5  $filter->postFilter( $filterChain); // 这个是在动作执行之后过滤  
2 否则,说明过滤完毕, $this->controller->runAction( $this->action); 直接执行动作。

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值