三 大概过程
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():
1
//
根据actionID创建action对象,这里生成的action对象分为定义在controller内联动作和自定义action,比如CViewAction
$action=
$this->createAction(
$actionID),如果创建动作失败,missingAction抛出404错误
2 beforeControllerAction(beforeControllerAction定义在CWebApplication,有时也在module里面)为真,才执行runActionWithFilters;
3 afterControllerAction
runActionWithFilters( $action, $this->filters()):
1
//
如果过滤器为空,直接运行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):
1
$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);
直接执行动作。
application构造函数:
1
2
3
4
5
6
7
8
9
10处理加载config中的preload, // 通过getComponent分别加载并初始化
11
run:
1
2
3
webapplication->processRequest():
1
2
3
runController:
1
2
3
4
控制器类
CController:默认控制器在CWebApplication::defaultController定义('site'),可以在配置文件修改
run():
1
2
3
runActionWithFilters( $action, $this->filters()):
1
2
runAction():
1
2
3
动作类
runWithParams():
1
2
3
4
runWithParamsInternal();
1
2
3
控制器类
CController:
render();
1
2
renderFile();
1
view
errorHandler
**********************************************************
runActionWithFilters
过滤:
CFilterChain(继承CList,提供数字索引存取功能,遍历)::create( $this, $action, $filters)->run();
首先创建过滤链,然后执行过滤
CFilterChain::create( $controller, $action, $filters):
1
2
注意:如果是字符串,控制器类controller必须要有"filter"+过滤器名的方法。
$chain::run();
1
2