Action Controller

Action Controller 过滤器

对于actions来说,过滤器可以使controllers运行共享的pre并且布置处理代码。在将要执行的action之前,这些过滤器可以用来作authentication,caching,或者auditing 。或者在action执行之后,用来定位或输出压缩。

过滤器访问request,response,和在链中的其他过滤器或者action(in the case of after filters)中的所有实例化的变量。另外,使前处理beforeFilter能够停止处理过程, 在执行将要执行的action时,通过执行返回错误值或者执行redirect或者render。 这个对于像authentication等特别有用,如果proper credentials没有在队列中,你也不用关心允许那个action运行。

Filter遗传

Controller遗传了分级结构,共享了下面的filters,但是子类也可以添加新的filters,并不会影响父类。For example:

class BankController extends AkActionController 
{
    function __construct()
    {
        $this->beforeFilter('_audit');
    }
 
    function _audit(&$controller)
    {
        // record the action and parameters in an audit log  
    }
}
 
class VaultController extends BankController 
{
    function __construct()
    {
        $this->beforeFilter('_verifyCredentials');
    }
 
    function _verifyCredentials(&$controller)
    {
        // make sure the user is allowed into the vault
    }
}

现在在BankController中的任何一个actions执行之前,将会调用audit method。在VaultController中, 首先audit method被调用, is called,然后是_verifyCredentials method。如果_audit method返回值为false,那么 _verifyCredentials和intended action将永远不会被执行。

Filter类型

filter能采用三种类型的一个: method reference, external class,或者inline method。第一个是最常见的,通过引用一个方法使之工作,在controller的遗传等级中通过使用方法的名字。 . 在上面的例子中,BankController和VaultController都使用了这个类型。

使用外部类可以更容易的重用一般的filters,例如output compression。外部的filter classes在任何类上,通过一个静态的filter方法来执行。然后从这个类去filter method。 Example:

class OutputCompressionFilter
{
    function filter(&$controller)
    {
        $controller->response->body = compress($controller->response->body);
    }
}
 
class NewspaperController extends AkActionController 
{
    function __construct()
    {
        $this->afterFilter(new OutputCompressionFilter());
    }
}

这个filter method通过之后,controller的实例并且能够访问controller的各个方面,并且能够操作他们。

Filter的排序链

使用beforeFilterafterFilter在已存在的链中添加指定的filters。一般来说这不错,但是有些时候你必须注意执行filters的顺序。当那个情形时,你可以使用 prependBeforeFilterprependAfterFilter。这些Filters会被追加到各自的链的开始,在rest之前执行他们。 For example:

class ShoppingController extends AkActionController 
{
    function __construct()
    {
        $this->beforeFilter('verifyOpenShop');
    }
}
 
 
class CheckoutController extends AkActionController 
{
    function __construct()
    {
        $this->prependBeforeFilter('ensureItemsInCart', 'ensureItemsInStock');
    }
}

CheckoutController的filter链现在是'ensureItemsInCart, ensureItemsInStock, verifyOpenShop''。所以任何一个filters返回值为false,如果商店没有开门,我们永远不能去四周转转。

你也许通过了每个类型复合的filter参数。

filters周围

除了个别的before和after filters的之外,对于指定的对象来说也应该能够处理before and after调用。当你需要before and after之间保持状态的有效性的时候,这是特别有用的。 such as the example of a benchmark filter below:

class WeblogController extends AkActionController 
{
    function __construct()
    {
        $this->aroundFilter(new BenchmarkingFilter());
    }
 
    // Before this action is performed, BenchmarkingFilter->before($controller) is executed
   function index()
   {
   }
    // After this action has been performed, BenchmarkingFilter->after($controller) is executed
}
 
class BenchmarkingFilter
{
    function before(&$controller)
    {
        start_timer();
    }
 
    function after(&$controller)
    {
        stop_timer();
        report_result();   
    }
}

Filter chain skipping

有些时候在父类中指定一个filter chain是非常方便的,他将会为大多数的子类保持真值, 但是不是所有的都需要。子类在意外情况下表现的很好,他们可以指定他们喜欢的filters来释放。 Examples

class ApplicationController extends AkActionController 
{
    function __construct()
    {
        $this->beforeFilter('authenticate');
    }
}
 
class WeblogController extends ApplicationController
{
    // will run the authenticate filter
}
 
class SignupController extends AkActionController 
{
    function __construct()
    {
        $this->skipBeforeFilter('authenticate');
    }
    // will not run the authenticate filter
}

Filter条件

Filters可以被限制在特定的actions中运行。在执行filter时可以通过监听被除外的actions和被包括的actions来清楚的说明。 可用的conditions是only or except, 他们两个both可以接受参考方法的任何数。 For example:

  class Journal extends AkActionController 
  {
      function __construct()
      {   // only require authentication if the current action is edit or delete
          $this->beforeFilter(array('_authorize'=>array('only'=>array('edit','delete')));
      }
 
      function _authorize(&$controller)
      {
        // redirect to login unless authenticated
      }
  }
 
filters-and-verification_cn.txt · Last modified: 2009/10/19 13:27 by 123.120.20.157
 

The Akelos Framework was created by Bermi Ferrer and other contributors.
Potions of the code and documentation have been ported from Ruby on Rails.

The Akelos Framework is released under the LGPL license.

"Akelos", "Akelos Framework", and the Akelos logo are trademarks of Bermi Labs All rights reserved.

Wiki driven by DokuWiki