在mvc的controller,主要是處理邏輯部份,會依照不同的path、參數、method…等,決定要處理的資料,以及要回傳什麼資訊給user。在Yii的controller都繼承至CController,需要導向哪個action,會在controller裡面設定完成。
Route
在Yii裡的程式進入點,都是透過project/index.php
這一隻程式,在根據webApp的confifg,決定預設執行哪支controller,以及在project/protected/controllers
對應的path。
例如在project/index.php
裡,會指定使用哪個config:
1 | $config=dirname(__FILE__).'/protected/config/main.php'; |
然後在main.php的config中,可以透過defaultController
指定預設controller:
1 | return Array( |
意思就是當path為根目錄時,會導向至PostController,例如url為:
1 | http://localhost/ |
與下面url相同,會藉由r
這個參數對照contoller/action
(當action未指定時,預設執行actionIndex這function,也可透過defaultAction自訂):
1 | http://localhost/index.php?r=post/index |
對應的project/protected/controllers/PostController
:
1 | class PostController extends CController { |
如果想自訂controller對應class的路徑,可使用controllerMap。
自訂url對應controller和action
使用自訂的url規則,去對應controller和action,可以修改webapp的config:
1 | return array( |
nginx的config設定,將除了靜態檔案以外的request,全部導向至index.php:
1 | server { |
Action
yii根據path導向至不同的controller,在透過controller指派action去處理。一般來說action可以直接寫在controller裡,也可以透過繼承CAction的方式,在controller定義此class。
在controller裡面定義action,有兩種方式:
只需要讓function名稱的開頭為
action
,在加上action的名稱即可。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19class PostController extends CController {
/**
* path為
/index.php?r=post
/index.php?r=post/index
**/
public function actionIndex(){
}
/**
* path為
/index.php?r=post/create
**/
public function actionCreate(){
}
}透過
actions
這個function,回傳定義好的config,對應不同CAction。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17class PostController extends CController {
public function actions()
{
return array(
// page action renders "static" pages stored under 'protected/views/site/pages'
// They can be accessed via: index.php?r=site/page&view=FileName
'page'=>array(
'class'=>'CViewAction',
),
// file path under 'protected/controllers/post/SayHelloAction'
'sayhello'=>array(
'class'=>'application.controllers.post.SayHelloAction',
),
);
}
}
CAction
繼承至CAction的方式,如下:
1 | class SayHelloAction extends CAction { |
yii也提供一些現成的action可以使用,像是:
CCaptchaAction
自動產生驗證碼,需要安裝php5-gd。CViewAction
可透過view這個參數,導向到不同頁面,而不需要針對每個頁面寫一個action。
Filter
yii的filter與action在controller的配置方式差不多,同樣可以在controller自訂filter的function,也可以class的方式繼承CFilter。
在controller寫filter方式:
1 | public function filterAccessControl($filterChain) |
如果呼叫$filterChain->run(),將會繼續往下執行下個filter和action,反則會中斷掉。
與action在controller宣告不同的是,filter的套用,必須在controller裡定義filters這個function,回傳定義的config:
1 | public function filters(){ |
上面這種方式,將會套用此controller的所有action,若要套用個別action,如下:
1 | public function filters(){ |
如果把+替換成-,指的就是除了edit和create這兩個不套用filter,剩下全部套用。
CFilter
CFilter將會透過preFilter這個function,決定要繼續向下執行或者停止,而postFilter則是會在preFilter向下執行時,才會去呼叫。
定義一個filter:
1 | class PerformanceFilter extends CFilter |
在controller中使用PerformanceFilter:1
2
3
4
5
6
7
8
9
10
11
12
13class PostController extends CController
{
......
public function filters()
{
return array(
array(
'application.filters.PerformanceFilter - edit, create',
'unit'=>'second',
),
);
}
}
filter第二個傳入參數unit,將會設定PerformanceFilter的unit值。所以除了第一個參數,會設定filter,之後的參數都會對應filter的public屬性。