2007年5月15日 星期二

CakePHP使用手冊-Controller

轉貼自 http://www.ezluk.org/

第一節



什麼是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

)

沒有留言:

網誌存檔

關於我自己

Aspire freedom , Hope to do Soming make self complete ~