CakePHP 2.x CookBook 中文版 第五章 控制器 之 组件
為什么80%的碼農都做不了架構師?>>> ??
組件
組件是在多個控制器中共享的邏輯包。如果你發現自己想要在控制器間復制粘貼某些東西時,你就應該考慮將一些功能包裝在一個組件中了。
CakePHP 還配備了一套漂亮的、對你有用的核心組件:
- Security(安全)
- Sessions(會話)
- Access control lists(訪問控制列表)
- Emails(電子郵件)
- Cookies
- Authentication(權限校驗)
- Request handling(請求處理)
- Pagination(分頁)
這些組件的詳細信息都在各自的章節中。 現在,我們將向你展示如何建立你自己的組件。 創建組件可以保持控制器代碼整潔,并且允許你在多個項目中重用代碼。
配置組件
一些核心組件需要配置。需要配置的組件有?授權、?Cookie?和?電子郵件組件?等。 對于一般的組件,通常在$components?數組或者控制器的?beforeFilter?方法中進行配置:
class PostsController extends AppController { public $components = array( 'Auth' => array( 'authorize' => array('controller'), 'loginAction' => array('controller' => 'users', 'action' => 'login') ), 'Cookie' => array('name' => 'CookieMonster') );這是使用?$components?數組配置組件的例子。所有的核心組件都允許使用這種方式進行配置。此外,你也可以在控制器的?beforeFilter()?方法中配置組件。 這種方式通常用在你需要將一個函數的結果賦與一個組件屬性的情況下。上面的例子還可以表示成:
public function beforeFilter() { $this->Auth->authorize = array('controller'); $this->Auth->loginAction = array('controller' => 'users', 'action' => 'login'); $this->Cookie->name = 'CookieMonster'; }然而,也有這種可能:一個組件的特定配置選項要在控制器的?beforeFilter()?運行前設置。 最后,一些組件允許在$components?數組中設置配置選項:
public $components = array( 'DebugKit.Toolbar' => array('panels' => array('history', 'session')) );通過查閱相關文檔可以確定每個組件都提供哪些配置選項。
className?是一個公用的設置選項,你可以借此給組件起個別名。當你想要用自定義的實現替換?$this->Auth?或者其它公用組件時,這個選項非常有用。
// app/Controller/PostsController.php class PostsController extends AppController { public $components = array( 'Auth' => array( 'className' => 'MyAuth' ) ); } // app/Controller/Component/MyAuthComponent.php App::uses('AuthComponent', 'Controller/Component'); class MyAuthComponent extends AuthComponent { // Add your code to override the core AuthComponent }上例的控制器中?$this->Auth?的別名為?MyAuthComponent?。
注解
在任何用到有別名的組件時,都要使用別名,包括在其它組件內引用。
使用組件
一旦你已經在控制器中包含了一些組件,用起來是非常簡單的。在控制器中每個元件都以屬性的方式使用。如果你已經在控制器中加載了?SessionComponent?和 the?CookieComponent?,你就可以像下面這樣訪問它們:
class PostsController extends AppController { public $components = array('Session', 'Cookie'); public function delete() { if ($this->Post->delete($this->request->data('Post.id')) { $this->Session->setFlash('Post deleted.'); $this->redirect(array('action' => 'index')); } }注解
由于以屬性身份加入到控制器中的模型和組件共享相同的 ‘命名空間’,你需要確保不給組件和模型相同的命名。
運行中加載組件
你也許不需要所有的組件在每個控制器方法中都可用。 這種情況下,你可以在運行時使用?Component Collection?加載一個組件。 在控制器內部,你可以按如下方式進行:
$this->OneTimer = $this->Components->load('OneTimer'); $this->OneTimer->getTime();組件回調
組件也提供一些請求生命周期回調,以允許它們延伸請求周期。 有關組件提供的回調的更詳細信息,請參閱?組件 API。
創建組件
假定我們的線上應用程序需要在其不同部分運行一個復雜的數學操作。我們可以創建一個組件包裝這個用在幾個不同控制器中的共享邏輯。
第一步是新的組件文件和類。創建的文件為?/app/Controller/Component/MathComponent.php。其基本結構如下:
App::uses('Component', 'Controller'); class MathComponent extends Component { public function doComplexOperation($amount1, $amount2) { return $amount1 + $amount2; } }注解
所有的組件必須繼承?Component。否則就會引發一個異常。
在控制器中包含組件
一旦組件完成,就可以通過將組件名稱放進控制器的?$components?數組的方式在應用程序控制器中使用它了(參見 “組件” 部分)。控制器將自動提供一個用組件命名的新屬性,通過這個屬性我們可以訪問組件的實例:
/* 生成一個新的組件變量 $this->Math 和一個標準的 $this->Session */ public $components = array('Math', 'Session');定義在?AppController?中的組件將與其它控制器中的組件合并。因此不需要二次定義相同的組件。
在控制器中包含組件時,你還可以定義一組參數傳遞給組件的構造函數。這些參數隨后將被組件處理:
public $components = array( 'Math' => array( 'precision' => 2, 'randomGenerator' => 'srand' ), 'Session', 'Auth' );這段代碼將包含了 precision 和 randomGenerator 的數組作為第二個參數傳遞給了?MathComponent::__construct()。根據約定,任何在組件上被傳遞的公共屬性也將擁有基于此設置的值。
在組件中使用其它組件
有時一個組件還需要使用其它組件。在這種情況下,你可以使用與在控制器中包含組件相同的方式,在一個組件中包含另一個組件 - 使用?``$components` 變量:
// app/Controller/Component/CustomComponent.php App::uses('Component', 'Controller'); class CustomComponent extends Component { // the other component your component uses public $components = array('Existing'); public function initialize(Controller $controller) { $this->Existing->foo(); } public function bar() { // ... } } // app/Controller/Component/ExistingComponent.php App::uses('Component', 'Controller'); class ExistingComponent extends Component { public function foo() { // ... } }組件 API
class?Component組件基類為通過?ComponentCollection?延遲加載其它組件以及處理公共設置提供了幾個方法。它還為所有的組件回調提供了屬性。
Component::__construct( ComponentCollection $collection,? $settings = array())組件基類構造函數。作為公共屬性的所有?$settings?也將有與?settings?內設置的值匹配的值。
回調
Component::initialize( Controller $controller)initialize 方法在控制器的 beforeFilter 方法之前被調用。
Component::startup( Controller $controller)startup 方法在控制器的 beforeFilter 之后但在控制器執行當前動作處理之前被調用。
Component::beforeRender( Controller $controller)beforeRender 方法在執行請求動作邏輯之后,控制器渲染視圖和布局之前被調用。
Component::shutdown( Controller $controller)shutdown 方法在輸出傳送給瀏覽器之前被調用。
Component::beforeRedirect( Controller $controller,? $url,? $status=null,? $exit=true)beforeRedirect 方法在控制器跳轉方法被調用之后,所有其它方法調用之前被調用。如果這個方法返回假,將不再繼續完成請求的轉向。$url、$status 和 $exit 變量對于控制器方法的意義相同。你還能返回一個字符串,作為轉向的 url,或者返回帶有鍵 ‘url’ 的關聯數組,此數組的 ‘status’ 和 ‘exit’ 元素是可選的。
轉載于:https://my.oschina.net/lht007/blog/115893
總結
以上是生活随笔為你收集整理的CakePHP 2.x CookBook 中文版 第五章 控制器 之 组件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 打开IT运维外包的“黑盒”
- 下一篇: 转码网址