第一節
什麼是controller?
controller是用來管理應用程式裡的邏輯部分。
說更白一點,controller是用來管理一個model的邏輯。
例如,如果要建立一個管理影片的網站,應該會負責管理影片和租金的邏輯,就叫VideoController和RentalController。
Cake裡的controller名稱通常是複數。
程式裡的controller是一個繼承自AppController的類別。
Controller可以含有很多的Action,這些Action就是程式中呼叫顯示畫面的函式。
譯註:這些Action同時也是web應用程式用來回應使用者request的地方
AppController類別被定義在/app/app_controller.php內,含有的方法可有讓多個controller共用。
而它本身則繼承自Cake標準函式庫內的Controller類別。
Action就是controller裡的一個單一功能。當一個URL經過路由機制的解析後,會由
Dispatcher負責自動執行controller的Action。回到影片網站的例子,我們的VideoController應該
會包含view(),rent(),和search()等Action。這個controller會被定義在
/app/controllers/videos_controller.php中,程式碼像這樣:
class VideosController extends AppController
{
function view($id)
{
//action logic goes here..
}
function rent($customer_id, $video_id)
{
//action logic goes here..
}
function search($query)
{
//action logic goes here..
}
}使用下面所列的URL可以使用這些Action:
http://www.example.com/videos/view/253
http://www.example.com/videos/rent/5124/0-235253
http://www.example.com/videos/search/hudsucker+proxy但這些網頁看起來會長什麼樣子呢?我們還需要為每個Action定義一個view,下一章會
仔細說明,請拿出您的耐心,好好等待。這章我們會教您Cake的controller是多麼強桿,並教
您如何使用它。您會學到如果讓你的controller把資料交給view,轉交給使用者等等。
第二節
Controller的函式
雖然這一節主要著重於Cake的Controller裡常用的函式,
但請別忘了到http://api.cakephp.org查完整的資訊。
和view互動
- set
- string $var
- mixed $value
這個函式是用來把資料從controller傳到view最主要的方法。這函式可以把任何東西傳過去,從單一值到整個陣列皆可。
一但用過set()之後,view裡就可以存取這個變數。例如,在controller執行set('color','blue),view裡就多出一個變數叫$color。
- validateErrors
傳回儲存失敗時產生的錯誤
- validate
使用model的驗証規則驗証model的資料。詳細資料請看"資料驗証"一章。
- render
- string $action
- string $layout
- string $file
這個函式會在每個controller的Action結束後自動被呼叫,然後以這個Action被命名的view就會被畫上去,
所以通常不會用到它。你也可以用這個函式在controller的任何一個地方把view畫上去。
使用者重新導向
- redirect
- string $url
用這個函式來告訴你的使用者接者要去那裡。URL變數可以填Cake內部的URL,也可以填完整的URL(http://....)。
- flash
- string $message
- string $url
- int $pause
這個函式會在快顯的layout(定義在app/views/layouts/flash.thtml)中顯示$message,
暫停幾秒,然後將使用者重導到$url指定的地方。
Cake的redirect()和flash()
二個函式並不會呼叫exit()。如果要讓程式在redirect()或
flash()停止,必需在二個函式之後立該呼叫exit()。
在不同的情形下,也有可能想要return而不是要exit()(例如,可能需要執行一些回呼函式)
Controller 的回呼函式
Cake的controller提供了相當多的回呼函式讓您在重要Action之前和之後有機會做些事。
想要使用它們,只要在controller裡宣告這些函式,自然可以使用傳入的參數和傳回值。
- beforeFilter
在controller的每一個Action之前呼叫。這是檢查session和使用者的好地方。
- afterFilter
每個Action之後呼叫。
- beforeRender
在Action執行完成之後,要畫view之前呼叫。
其他有用的函式
這些都是Cake裡Object類別的函式,而他們同樣都可以在Controller裡使用:
- requestAction
- string $url
- array $extra
這函式可以允許你在任何地方呼叫controller的Action,傳回畫好的view。
$url是Cake的URL(/controllername/actionname/params)。
如果$extra陣列含有'return'鍵,controller Action的AutoRender會自動被設成true。
可以透過requestAction從其他controller的Action取得資料,或從controller取得完整個畫面。
我們只要在view裡任何需要資料的地方呼叫requestAction就可以很輕易的取得資料。
// Here is our simple controller:
class UsersController extends AppController
{
function getUserList()
{
return $this->User->findAll();
}
}想像一下我們需要建立一個簡單的表單顯示系統內的使用者。
為了避免在另一個controller內再重寫同樣的程式碼,我們可以直接使用requestAction()來呼叫UsersController::getUserList()。
class ProductsController extends AppController
{
function showUserProducts()
{
$this->set('users', $this->requestAction('/users/getUserList'));
// 現在,view裡的$user變數裡會有來自UsersController::getUserList()
// 的資料。
}
}
如果程式裡有個很常用的元素,內容又不是固定的,則可以利用requestAction()取回它的view再放到畫面上。
如果$extra陣列含有'return'鍵則會把整個畫面一併傳回,而不單單只是把資料由UsersController::getUserList傳回,
我們真正需要的也就是要那個Action的畫面(裡頭可能含有一個表格)。
這麼做省下不少寫重覆程式碼的時間。
class ProgramsController extends AppController
{
function viewAll()
{
$this->set('userTable', $this->requestAction('/users/getUserList', array('return')));
// 現在我們可以在view裡echo $userTable,畫面上就會顯示/users/getUserList
// 會畫出來的畫面
}
}請注意一點,透過requestAction()呼叫的Action會被畫在空的layout上,
所以不必擔心layout會被畫在layout裡的問題。
使用AJAX時requestAction()最有用,因為AJAX常常需要在更新時顯示部分畫面。
- log
- string $message
- int $type = LOG_ERROR
可以用這個函式把web應用程式內所發生的任何事件記錄下來。
記錄的結果會被放在Cake的/tmp目錄下。
如果$type和PHP的LOG_DEBUG常數相同,訊息就會被常成除錯訊息記起來。
其他類則都被當作錯誤記錄。
// 在controller裡可以使用log()寫內容:
$this->log('Mayday! Mayday!');
//Log entry:
06-03-28 08:06:22 Error: Mayday! Mayday!
$this->log("Look like {$_SESSION['user']} just logged in.", LOG_DEBUG);
//Log entry:
06-03-28 08:06:22 Debug: Looks like Bobby just logged in.- postConditions
- array $data
把$this->data傳進入,它會把資料轉成model使用的格式傳回。
例如,有一個找人的表單:
// app/views/people/search.thtml:
<?php echo $html->input('Person/last_name'); ?>提交表單後,結果會放在$this->data陣列中,內容像這樣:
Array
(
[Person] => Array
(
[last_name] => Anderson
)
)此時,我們可以使用postConditions()把資料改變,讓model使用:
// app/controllers/people_controller.php:
$conditions = $this->postConditions($this->data);
// 呼叫後傳回的陣列長的像這樣:
Array
(
[Person.last_name] => Anderson
)
// 這種格式可以直接傳入model的查詢函式內查詢:
$this->Person->findAll($conditions);第三節
Controller的變數
控制controller裡的一些特殊變數可以開啟Cake額外的功能:
$name
PHP 4無法得知目前這個類別的名稱。如果執行上遇到什麼問題,可以試試把這個變數
設成類別名稱。
$uses
你的controller同時使用二個以上的model嗎?
FragglesController會自動載入$this->Fraggle,如果你也想取用$this->Smurf,
試試把下面的程式放到你的controller中:
var $uses = array('Fraggle','Smurf');注意這裡同時也要把Fraggle也放進來。
$helpers
用這個變數叫你的controller把helpler載到它的view裡。
HTML helper會自動載入,要載入其他的,就得透過這個變數:
var $helpers = array('Html','Ajax','Javascript');記住這裡也要把HTML Helper放進入,如果你還要使用它。
在沒定義$helper時,controller會自動載入它,一但定義了$helpers,就不會自動載入了。
$layout
在此設定這個controller要使用的layout。
$autoRender
如果把這個值設成false,所有Action完成後將不會自動把畫面輸出。
$beforeFilter
如果想在Action執行前做一點別的事,就可以用這個變數。
這個變數很好用,你可以在Action執行前先看看使用者權限是否足夠。
只要把Action發生前想要執行的函式名稱放在陣列內就行了:
class ProductsController extends AppController
{
var $beforeFilter = array('checkAccess');
function checkAccess()
{
//檢查使用者的程式放這兒....
}
function index()
{
//當這個Action被呼叫前,checkAccess()會先被呼叫。
}
}$components
就和$helpers 與 $uses一樣,這個變數會把需要的compoment載入:
var $components = array('acl');Section 4
Controller 的參數
Controller的參數放在Cake controller的$this->params。
這個變數用來取得傳入controller的資料,存取目前request的資訊。
$this->params最常用在讀取透過POST和GET傳進controller的訊息。
$this->data
用來處理從HTML Helper表單傳過來的POST資料。
// 用來建立表單元件的 HTML Helper
$html->input('User/first_name');
// 畫成HTML時,看起來像這樣:
<input name="data[User][first_name]" value="" type="text" />
// 透過POST提交到controller時,則出現在
// $this->data['User']['first_name']
Array
(
[data] => Array
(
[User] => Array
(
[username] => mrrogers
[password] => myn3ighb0r
[first_name] => Mister
[last_name] => Rogers
)
)
)
$this->params['form']
任何一個表單所傳過來的POST資料都放在這裡,同樣的資料也可以在$_FILES找到。
$this->params['bare']
如果現在的layout是空的,就存'1',不是就存'0'。
$this->params['ajax']
如果現在的layout是AJAX就存'1',否則就存'0'。
$this->params['controller']
存放目前處理request的controller名稱。例如,URL /posts/view/1被呼叫時,
$this->params['controller']會等於"posts"。
$this->params['action']
存放目前處理request的Action名稱。例如,若URL /posts/view/1被呼叫,
$this->params['action']會等於'view'。
$this->params['pass']
存放目前request的GET字串。例如,若URL /posts/view/?var1=3&var2=4被呼叫,
$this->params['pass'] 會等於"?var1=3&var2=4"。
$this->params['url']
以鍵-值的格式存放目前的URL。例如,如果URL是/posts/view/?var1=3&var2=4,
$this->params['url'] 長得像這樣:
[url] => Array
(
[url] => posts/view
[var1] => 3
[var2] => 4
)
沒有留言:
張貼留言