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.
}