1.
public
function
run()
数组
2.
{
app
3.
$this
->onBeginRequest(
new
CEvent(
$this
));
框架
4.
$this
->processRequest();
yii
5.
$this
->onEndRequest(
new
CEvent(
$this
));
函数
6.
}
ui
01.
public
function
processRequest()
02.
{
03.
if
(
is_array
(
$this
->catchAllRequest) && isset(
$this
->catchAllRequest[0]))
04.
{
05.
$route
=
$this
->catchAllRequest[0];
06.
foreach
(
array_splice
(
$this
->catchAllRequest,1)
as
$name
=>
$value
)
07.
$_GET
[
$name
]=
$value
;
08.
}
09.
else
10.
$route
=
$this
->getUrlManager()->parseUrl(
$this
->getRequest());
11.
$this
->runController(
$route
);
12.
}
01.
public
function
runController(
$route
)
02.
{
03.
//根据route建立Controller对象数组
04.
if
((
$ca
=
$this
->createController(
$route
))!==null)
05.
{
06.
//包含controller对象和actionID
07.
list(
$controller
,
$actionID
)=
$ca
;
08.
//TODO::这里是干什么用的
09.
$oldController
=
$this
->_controller;
10.
$this
->_controller=
$controller
;
11.
//调用controller对象的初始化方法
12.
$controller
->init();
13.
//使用actionID运行这个Controller
14.
$controller
->run(
$actionID
);
15.
$this
->_controller=
$oldController
;
16.
}
17.
Else
18.
//若是没有找到对应的Controller,跳转到404页面
19.
throw
new
CHttpException(404,Yii::t(
'yii'
,
'Unable to resolve the request "{route}".'
,
20.
array
(
'{route}'
=>
$route
===
''
?
$this
->defaultController:
$route
)));
21.
}
01.
/**
02.
* ……
03.
* 这个方法如下面的顺序建立一个控制器
04.
* 1. 若是第一个字段在controllerMap(初始配置)中,则使用对应的控制器配置来建立控制器
05.
* 2.若是第一个字段是一个模块(module)ID,则使用相应的模块来建立控制器
06.
* 3.若是经过上面两项均没法建立控制器,将会搜索controllerPath(根目录对应的controller文件夹)来建立对应的控制器。
07.
* ……
08.
*/
09.
public
function
createController(
$route
,
$owner
=null)
10.
{
11.
// $owner为空则设置为$this,即 $_app对象
12.
if
(
$owner
===null)
13.
$owner
=
$this
;
14.
// $route为空设置为defaultController,在$config里配置
15.
if
((
$route
=trim(
$route
,
'/'
))===
''
)
16.
$route
=
$owner
->defaultController;
17.
$caseSensitive
=
$this
->getUrlManager()->caseSensitive;
18.
19.
$route
.=
'/'
;
20.
// 逐一取出 $route 按 ‘/’分割后的第一段进行处理
21.
while
((
$pos
=
strpos
(
$route
,
'/'
))!==false)
22.
{
23.
// $id 里存放的是 $route 第一个 ‘/’前的部分
24.
$id
=
substr
(
$route
,0,
$pos
);
25.
if
(!preg_match(
'/^\w+$/'
,
$id
))
26.
return
null;
27.
if
(!
$caseSensitive
)
28.
$id
=
strtolower
(
$id
);
29.
// $route 存放’/’后面部分
30.
$route
=(string)
substr
(
$route
,
$pos
+1);
31.
if
(!isset(
$basePath
))
// 完整$route的第一段
32.
{
33.
// 若是$id在controllerMap[]里作了映射
34.
// 直接根据$id建立controller对象
35.
if
(isset(
$owner
->controllerMap[
$id
]))
36.
{
37.
return
array
(
38.
Yii::createComponent(
$owner
->controllerMap[
$id
],
$id
,
$owner
===
$this
?null:
$owner
),
39.
$this
->parseActionParams(
$route
),
40.
);
41.
}
42.
43.
// $id 是系统已定义的 module,根据$id取得module对象做为$owner参数来createController
44.
if
((
$module
=
$owner
->getModule(
$id
))!==null)
45.
return
$this
->createController(
$route
,
$module
);
46.
// 控制器所在的目录
47.
$basePath
=
$owner
->getControllerPath();
48.
$controllerID
=
''
;
49.
}
50.
else
51.
$controllerID
.=
'/'
;
52.
$className
=ucfirst(
$id
).
'Controller'
;
53.
$classFile
=
$basePath
.DIRECTORY_SEPARATOR.
$className
.
'.php'
;
54.
// 控制器类文件存在,则require并建立控制器对象&返回
55.
if
(
is_file
(
$classFile
))
56.
{
57.
if
(!
class_exists
(
$className
,false))
58.
require
(
$classFile
);
59.
if
(
class_exists
(
$className
,false) &&
is_subclass_of
(
$className
,
'CController'
))
60.
{
61.
$id
[0]=
strtolower
(
$id
[0]);
62.
return
array
(
63.
new
$className
(
$controllerID
.
$id
,
$owner
===
$this
?null:
$owner
),
64.
$this
->parseActionParams(
$route
),
65.
);
66.
}
67.
return
null;
68.
}
69.
// 未找到控制器类文件,多是多级目录,继续往子目录搜索
70.
$controllerID
.=
$id
;
71.
$basePath
.=DIRECTORY_SEPARATOR.
$id
;
72.
}
73.
}
01.
public
function
run(
$actionID
)
02.
{
03.
if
((
$action
=
$this
->createAction(
$actionID
))!==null)
04.
{
05.
if
((
$parent
=
$this
->getModule())===null)
06.
$parent
=Yii::app();
07.
if
(
$parent
->beforeControllerAction(
$this
,
$action
))
08.
{
09.
$this
->runActionWithFilters(
$action
,
$this
->filters());
10.
$parent
->afterControllerAction(
$this
,
$action
);
11.
}
12.
}
13.
else
14.
$this
->missingAction(
$actionID
);
15.
}
01.
public
function
createAction(
$actionID
)
02.
{
03.
// 为空设置为defaultAction
04.
if
(
$actionID
===
''
)
05.
$actionID
=
$this
->defaultAction;
06.
// 控制器里存在 'action'.$actionID 的方法,建立CInlineAction对象
07.
if
(method_exists(
$this
,
'action'
.
$actionID
) &&
strcasecmp
(
$actionID
,
's'
))
// we have actions method
08.
return
new
CInlineAction(
$this
,
$actionID
);
09.
// 不然根据actions映射来建立Action对象(就是咱们本身建立的继承自CAtion的对象)
10.
else
11.
return
$this
->createActionFromMap(
$this
->actions(),
$actionID
,
$actionID
);
12.
}
01.
class
CInlineAction
extends
CAction
02.
{
03.
public
function
run()
04.
{
05.
$method
=
'action'
.
$this
->getId();
06.
$this
->getController()->
$method
();
07.
}
08.
public
function
runWithParams(
$params
)
09.
{
10.
$methodName
=
'action'
.
$this
->getId();
11.
$controller
=
$this
->getController();
12.
$method
=
new
ReflectionMethod(
$controller
,
$methodName
);
13.
//若是run方法有参数的话,那么就用反射来处理,最后调用run方法
14.
if
(
$method
->getNumberOfParameters()>0)
15.
return
$this
->runWithParamsInternal(
$controller
,
$method
,
$params
);
16.
//直接调用咱们action
17.
else
18.
return
$controller
->
$methodName
();
19.
}
20.
}
01.
public
function
runWithParams(
$params
)
02.
{
03.
$method
=
new
ReflectionMethod(
$this
,
'run'
);
04.
//若是run方法有参数的话,那么就用反射来处理,最后调用run方法
05.
if
(
$method
->getNumberOfParameters()>0)
06.
return
$this
->runWithParamsInternal(
$this
,
$method
,
$params
);
07.
//直接调用CInlineAction的run方法
08.
else
09.
return
$this
->run();
10.
}
01.
public
function
run(
$actionID
)
02.
{
03.
if
((
$action
=
$this
->createAction(
$actionID
))!==null)
04.
{
05.
if
((
$parent
=
$this
->getModule())===null)
06.
$parent
=Yii::app();
07.
if
(
$parent
->beforeControllerAction(
$this
,
$action
))
08.
{
09.
$this
->runActionWithFilters(
$action
,
$this
->filters());
10.
$parent
->afterControllerAction(
$this
,
$action
);
11.
}
12.
}
13.
else
14.
$this
->missingAction(
$actionID
);
01.
public
function
runActionWithFilters(
$action
,
$filters
)
02.
{
03.
// 控制器里没有设置过滤器
04.
if
(
empty
(
$filters
))
05.
$this
->runAction(
$action
);
06.
// 控制器里设置过滤器
07.
else
08.
{
09.
$priorAction
=
$this
->_action;
10.
$this
->_action=
$action
;
11.
// 建立过滤器链对象并运行,其实这一步的执行很简单,就是按照过滤规则先过滤一下,而后再来执行runAction($action)方法
12.
CFilterChain::create(
$this
,
$action
,
$filters
)->run();
13.
$this
->_action=
$priorAction
;
14.
}
15.
}
01.
public
function
runAction(
$action
)
02.
{
03.
$priorAction
=
$this
->_action;
04.
$this
->_action=
$action
;
05.
if
(
$this
->beforeAction(
$action
))
06.
{
07.
if
(
$action
->runWithParams(
$this
->getActionParams())===false)
08.
$this
->invalidActionParams(
$action
);
09.
else
10.
$this
->afterAction(
$action
);
11.
}
12.
$this
->_action=
$priorAction
;
13.
}
01.
public
function
runWithParams(
$params
)
02.
{
03.
$methodName
=
'action'
.
$this
->getId();
04.
$controller
=
$this
->getController();
05.
$method
=
new
ReflectionMethod(
$controller
,
$methodName
);
06.
if
(
$method
->getNumberOfParameters()>0)
07.
return
$this
->runWithParamsInternal(
$controller
,
$method
,
$params
);
08.
else
09.
return
$controller
->
$methodName
();
10.
}