Symfony中控制層包含了連接業(yè)務(wù)邏輯與表現(xiàn)的代碼,控制層為不同的使用分成了幾個不同的部分。
l 前端控制器是指向應(yīng)用的唯一入口
l 動作包含了應(yīng)用的邏輯,他們檢查請求的完整性并準(zhǔn)備好表示層需要的數(shù)據(jù)
l 請求、響應(yīng)和Session對象提供訪問請求參數(shù)、響應(yīng)參數(shù)以及持久的用戶數(shù)據(jù),這些數(shù)據(jù)在控制層使用的很普遍
l 過濾器是每個請求都要執(zhí)行的代碼的一部分,無論在動作前還是在動作后。可以自創(chuàng)過濾器。
所有WEB請求都將被前端控制器捕獲,前端控制是給定環(huán)境下整個應(yīng)用的唯一入口點。當(dāng)前端控制接到一個請求,他使用路由系統(tǒng)匹配用戶輸入的URL的動作名和模塊名。例如:
http://localhost/index.php/mymodule/myAction URL調(diào)用了index.php腳本(也就是前端控制器),他被理解為:動作-myAction,模塊-mymodule |
前端控制器分發(fā)請求,他僅執(zhí)行那些通用的和共同的代碼,包括:
l 定義核心常量
l 定位symfony庫
l 載入和初始化核心框架類
l 載入配置信息
l 解碼請求URL,獲取要執(zhí)行的動作和請求參數(shù)
l 如果動作不存在則專項404錯誤
l 激活過濾器(比如,如果需要身份認(rèn)證)
l 執(zhí)行過濾器,第一次
l 執(zhí)行動作,遞交視圖
l 執(zhí)行過濾器,第二次
l 輸出響應(yīng)。
默認(rèn)前端控制器叫作index.php,在項目的WEB/目錄,他是一個簡單的PHP文件,如下:
<?php define('SF_ROOT_DIR', realpath(dirname(__FILE__).'/..')); define('SF_APP', 'myapp'); define('SF_ENVIRONMENT', 'prod'); define('SF_DEBUG', false); require_once(SF_ROOT_DIR.DIRECTORY_SEPARATOR.'apps'.DIRECTORY_SEPARATOR.SF_APP.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'config.php'); sfContext::getInstance()->getController()->dispatch(); |
這個文件在前面已經(jīng)介紹過了:首先定義幾個變量,然后引入應(yīng)用的配置config.php,最后調(diào)用sfController(這是symfony MVC架構(gòu)中的核心控制器對象)的dispatch()方法。最后一步將被過濾器鏈捕獲。
每個環(huán)境存在一個前端控制器,環(huán)境定義在SF_ENVIRONMENT常量中。
創(chuàng)建新環(huán)境就和創(chuàng)建新的前端控制器一樣簡單,比如,你需要一個staging環(huán)境以使你的應(yīng)用上線之前可以被客戶測試。要創(chuàng)建staging環(huán)境,拷貝web/myapp_dev.php到web/myapp_staging.php,然后修改SF_ENVIRONMENT常量為staging。現(xiàn)在,你可以在所有的配置文件中增加staging段了設(shè)置新環(huán)境所需要的東西,看下面的示例:
## app.yml staging: mail: webmaster: dummy@mysite.com contact: dummy@mysite.com all: mail: webmaster: webmaster@mysite.com contact: contact@mysite.com |
##查看結(jié)果 http://localhost/myapp_staging.php/mymodule/index |
在命令行或者計劃任務(wù)中訪問symfony類和特性的時候需要使用批處理文件。批處理文件的開頭與前端控制器的開頭一樣——除了前端控制器的分發(fā)部分不要。
<?php define('SF_ROOT_DIR', realpath(dirname(__FILE__).'/..')); define('SF_APP', 'myapp'); define('SF_ENVIRONMENT', 'prod'); define('SF_DEBUG', false); require_once(SF_ROOT_DIR.DIRECTORY_SEPARATOR.'apps'.DIRECTORY_SEPARATOR.SF_APP.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'config.php'); // 添加批處理代碼 |
動作是應(yīng)用的心臟,因為他包含了所有應(yīng)用的邏輯。他們使用模型并定義變量給視圖。當(dāng)在應(yīng)用中使用一個請求,URL中定義了一個動作和請求的參數(shù)。
動作是moduleNameActions類(繼承自sfActions類)中名為executeActionName的方法,以模塊組織在一起,模塊動作類存儲在actions目錄的actions.class.php文件中。
只有WEB目錄下的文件能夠被外部訪問,前端控制腳本、圖片、樣式表和JS文件是公開的,即使PHP中方法不區(qū)分大小寫,但symfony中區(qū)分,所以不要忘了動作方法必須以小寫execute開始,緊跟著是首字母大寫的動作名。 |
如果動作類變得很大,你應(yīng)該做一些分解并把代碼放在模型層,動作應(yīng)該盡量的保證短小(幾行最好),所有的業(yè)務(wù)邏輯都應(yīng)該放在模型層中。
可以一個動作一個文件,文件的名稱為動作名加Action.class.php,類名為動作名加Action,只是記得類繼承自sfAction而非sfActions。
動作類提供了一種訪問控制器相關(guān)信息與核心symfony對象的方法,下面演示了如何使用:
<?php define('SF_ROOT_DIR', realpath(dirname(__FILE__).'/..')); define('SF_APP', 'myapp'); define('SF_ENVIRONMENT', 'prod'); define('SF_DEBUG', false); require_once(SF_ROOT_DIR.DIRECTORY_SEPARATOR.'apps'.DIRECTORY_SEPARATOR.SF_APP.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'config.php'); class mymoduleActions extends sfActions { public function executeIndex() { // Retrieving request parameters $password = $this->getRequestParameter('password'); // Retrieving controller information $moduleName = $this->getModuleName(); $actionName = $this->getActionName(); // Retrieving framework core objects $request = $this->getRequest(); $userSession = $this->getUser(); $response = $this->getResponse(); $controller = $this->getController(); $context = $this->getContext(); // Setting action variables to pass information to the template $this->setVar('foo', 'bar'); $this->foo = 'bar'; // Shorter version } } |
上下文: 在前端控制器中一個sfContext::getInstance()的調(diào)用。在動作中,getContext()方法是單例模式(即所有的調(diào)用都是第一個實例,這對于存儲指向與給定請求相關(guān)的symfony核心對象的索引的情況是非常有用的)。 sfController:控制器對象 (->getController()) sfRequest:請求對象 (->getRequest()) sfResponse:響應(yīng)對象 (->getResponse()) sfUser:用戶Session對象 (->getUser()) sfDatabaseConnection:數(shù)據(jù)庫鏈接
生活不易,碼農(nóng)辛苦 |