天天看點

CakePHP 2.x CookBook 中文版 第五章 控制器 之 元件 元件

元件

元件是在多個控制器中共享的邏輯包。如果你發現自己想要在控制器間複制粘貼某些東西時,你就應該考慮将一些功能包裝在一個元件中了。

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’ 元素是可選的。

版權聲明:本文為CSDN部落客「weixin_34314962」的原創文章,遵循CC 4.0 BY-SA版權協定,轉載請附上原文出處連結及本聲明。

原文連結:https://blog.csdn.net/weixin_34314962/article/details/91816830

php