Home  >  Article  >  Backend Development  >  Summary of the use of filters in PHP's Yii framework, yii filter_PHP tutorial

Summary of the use of filters in PHP's Yii framework, yii filter_PHP tutorial

WBOY
WBOYOriginal
2016-07-12 08:55:131009browse

A summary of the use of filters in PHP's Yii framework, yii filters

Introduction to Yii filters

A filter is a piece of code that can be configured to execute before or after a controller action. For example, access control filters will be executed to ensure that the user is authenticated before performing the requested action; performance filters can be used to measure the time it takes for the controller to execute.

An action can have multiple filters. Filters are executed in the order they appear in the filter list. Filters can prevent actions and other subsequent filters from executing.

There are two ways to write filters:

  • Method-based filters
  • Filter based on custom filter class

No matter what kind of filter you use, you must override the controller's public function filters() method in the controller to set which filter will act on which action.

Method-based filters

Writing a method-based filter requires three steps:

Write actions in the controller;
Write the filter function in the controller. The function name must be prefixed with filter, such as: function filterAccessControl();
Rewrite the filters() method of the parent class CController to define the relationship between filters and actions;
Example:

<&#63;php 
   
  class UserController extends CController{ 
    ** 
     * 第一步:创建动作 
     */ 
      function actionAdd(){  
        echo "actionAdd"; 
      } 
      /** 
      * 第二步:创建基于方法的过滤器 
       */ 
      public function filterAddFilter($filterChain) { 
        echo "基于方法的过滤器UserController.filterAdd<br>"; 
        $filterChain->run(); 
      } 
      /** 
      * 第三步:重写父类CController的filters()方法,定义过滤器与动作的关系 
      * @see CController::filters() 
      */ 
      public function filters(){ 
        return array( 
      //定义过滤器与动作的关联关系 
          'addFilter + add', 
//         array( 
//             'application.filters.TestFilter',           
//         ), 
           
      ); 
    } 
  } 

Custom filter class

To customize the filter class, you need to write a separate filter class, inherit the CFilter class, and override some methods under the CFilter class. You can take a look at the code of the CFilter class. There is not much code in this class and it is still easy to understand.

Custom filter example:

<&#63;php 
class TestFilter extends CFilter{ 
  /** 
   * Performs the pre-action filtering. 
   * @param CFilterChain $filterChain the filter chain that the filter is on. 
   * @return boolean whether the filtering process should continue and the action 
   * should be executed. 
   */ 
  protected function preFilter($filterChain) 
  { 
    echo "--->TestFilter.preFilter.<br>"; 
    return true; 
  } 
   
  /** 
   * Performs the post-action filtering. 
   * @param CFilterChain $filterChain the filter chain that the filter is on. 
   */ 
  protected function postFilter($filterChain) 
  { 
    echo "--->TestFilter.postFilter.<br>"; 
  } 
} 


Register the binding relationship between the custom filter and the action in the controller:

/**
* 第三步:重写父类CController的filters()方法,定义过滤器与动作的关系 
* @see CController::filters() 
*/ 
ublic function filters(){ 
return array( 
  //定义过滤器与动作的关联关系 
    'addFilter + add', 
      array( 
          'application.filters.TestFilter',           
      ), 
     
); 


I customized a filter: TestFilter, which inherits the CFilter class and overrides the two main methods of the CFilter class: preFilter (pre-controller, runs before the action is executed) and postFilter (post-controller, runs after the action is executed) ).

Execution sequence of the two controllers

Suppose I bind the custom filter class written above to the actionAdd. Then, the custom filter inherits two methods from the parent class CFilter: preFilter and postFilter, and the execution order with the bound actionAdd is What kind of thing?

After testing, the execution order is: CFilter::preFilter--------->UserController::actionAdd--------->CFilter::postFilter.

In other words, filtering operations can be performed before and after the action is executed.

So how does it say at the beginning of the article that "Filters can prevent the execution of actions and other subsequent filters"?

You will know after reading the official comments of CFilter::preFilter:

@return boolean whether the filtering process should continue and the action should be executed.

CFilter::preFilter function returns by default
true; that is, subsequent actions and post-filters are executed by default. If in a custom filter class, override the CFilter::preFilter method and return
False; you can prevent subsequent actions and filters from executing!


Use filters

A filter is essentially a special type of behavior, so using a filter is the same as using a behavior. Filters can be declared in the controller class by overriding its yiibaseController::behaviors() method as follows:

public function behaviors()
{
  return [
    [
      'class' => 'yii\filters\HttpCache',
      'only' => ['index', 'view'],
      'lastModified' => function ($action, $params) {
        $q = new \yii\db\Query();
        return $q->from('user')->max('updated_at');
      },
    ],
  ];
}

The filter of a controller class is applied to all actions of the class by default. You can configure the yiibaseActionFilter::only attribute to explicitly specify which actions the controller applies to. In the above example, the HttpCache filter only applies to index and view actions. You can also configure the yiibaseActionFilter::except attribute to prevent some actions from executing filters.

In addition to controllers, filters can be declared in modules or application bodies. After declaration, the filter will be applied to all controller actions belonging to the module or application body, unless the filter's yiibaseActionFilter::only and yiibaseActionFilter::except attributes are configured as above.

Supplement: When declaring filters in the module or application body, use routes instead of action IDs in the yiibaseActionFilter::only and yiibaseActionFilter::except attributes, because only using the action ID in the module or application body cannot uniquely specify the specific action. .
When an action has multiple filters, they are executed sequentially according to the following rules:

Pre-filter

  • Execute the filters listed in behaviors() in the application body in order.
  • Execute the filters listed in behaviors() in the module in order.
  • Execute the filters listed in behaviors() in the controller in order.
  • If any filter terminates action execution, subsequent filters (including pre-filtering and post-filtering) will no longer be executed.
  • Execute the action after successfully passing pre-filtering.

Post filter

  • Execute the filters listed in behaviors() in the controller in reverse order.
  • Execute the filters listed in behaviors() in the module in reverse order.
  • Execute the filters listed in behaviors() in the application body in reverse order.

Create filter

继承 yii\base\ActionFilter 类并覆盖 yii\base\ActionFilter::beforeAction() 和/或 yii\base\ActionFilter::afterAction() 方法来创建动作的过滤器,前者在动作执行之前执行,后者在动作执行之后执行。 yii\base\ActionFilter::beforeAction() 返回值决定动作是否应该执行, 如果为false,之后的过滤器和动作不会继续执行。

下面的例子申明一个记录动作执行时间日志的过滤器。

namespace app\components;

use Yii;
use yii\base\ActionFilter;

class ActionTimeFilter extends ActionFilter
{
  private $_startTime;

  public function beforeAction($action)
  {
    $this->_startTime = microtime(true);
    return parent::beforeAction($action);
  }

  public function afterAction($action, $result)
  {
    $time = microtime(true) - $this->_startTime;
    Yii::trace("Action '{$action->uniqueId}' spent $time second.");
    return parent::afterAction($action, $result);
  }
}


核心过滤器

Yii提供了一组常用过滤器,在yii\filters命名空间下,接下来我们简要介绍这些过滤器。

1.yii\filters\AccessControl

AccessControl提供基于yii\filters\AccessControl::rules规则的访问控制。 特别是在动作执行之前,访问控制会检测所有规则并找到第一个符合上下文的变量(比如用户IP地址、登录状态等等)的规则, 来决定允许还是拒绝请求动作的执行,如果没有规则符合,访问就会被拒绝。

如下示例表示表示允许已认证用户访问create 和 update 动作,拒绝其他用户访问这两个动作。

use yii\filters\AccessControl;

public function behaviors()
{
  return [
    'access' => [
      'class' => AccessControl::className(),
      'only' => ['create', 'update'],
      'rules' => [
        // 允许认证用户
        [
          'allow' => true,
          'roles' => ['@'],
        ],
        // 默认禁止其他用户
      ],
    ],
  ];
}


2.认证方法过滤器

认证方法过滤器通过HTTP Basic Auth或OAuth 2 来认证一个用户,认证方法过滤器类在 yii\filters\auth 命名空间下。

如下示例表示可使用yii\filters\auth\HttpBasicAuth来认证一个用户,它使用基于HTTP基础认证方法的令牌。 注意为了可运行,yii\web\User::identityClass 类必须 实现 yii\web\IdentityInterface::findIdentityByAccessToken()方法。

use yii\filters\auth\HttpBasicAuth;

public function behaviors()
{
  return [
    'basicAuth' => [
      'class' => HttpBasicAuth::className(),
    ],
  ];
}

认证方法过滤器通常在实现RESTful API中使用。

3.yii\filters\ContentNegotiator

ContentNegotiator支持响应内容格式处理和语言处理。 通过检查 GET 参数和 Accept HTTP头部来决定响应内容格式和语言。

如下示例,配置ContentNegotiator支持JSON和XML响应格式和英语(美国)和德语。

use yii\filters\ContentNegotiator;
use yii\web\Response;

public function behaviors()
{
  return [
    [
      'class' => ContentNegotiator::className(),
      'formats' => [
        'application/json' => Response::FORMAT_JSON,
        'application/xml' => Response::FORMAT_XML,
      ],
      'languages' => [
        'en-US',
        'de',
      ],
    ],
  ];
}


在应用主体生命周期过程中检测响应格式和语言简单很多, 因此ContentNegotiator设计可被引导启动组件调用的过滤器。 如下例所示可以将它配置在应用主体配置。

use yii\filters\ContentNegotiator;
use yii\web\Response;

[
  'bootstrap' => [
    [
      'class' => ContentNegotiator::className(),
      'formats' => [
        'application/json' => Response::FORMAT_JSON,
        'application/xml' => Response::FORMAT_XML,
      ],
      'languages' => [
        'en-US',
        'de',
      ],
    ],
  ],
];


补充: 如果请求中没有检测到内容格式和语言,使用formats和languages第一个配置项。
4.yii\filters\HttpCache

HttpCache利用Last-Modified 和 Etag HTTP头实现客户端缓存。例如:

use yii\filters\HttpCache;

public function behaviors()
{
  return [
    [
      'class' => HttpCache::className(),
      'only' => ['index'],
      'lastModified' => function ($action, $params) {
        $q = new \yii\db\Query();
        return $q->from('user')->max('updated_at');
      },
    ],
  ];
}


5.yii\filters\PageCache

PageCache实现服务器端整个页面的缓存。如下示例所示,PageCache应用在index动作, 缓存整个页面60秒或post表的记录数发生变化。它也会根据不同应用语言保存不同的页面版本。

use yii\filters\PageCache;
use yii\caching\DbDependency;

public function behaviors()
{
  return [
    'pageCache' => [
      'class' => PageCache::className(),
      'only' => ['index'],
      'duration' => 60,
      'dependency' => [
        'class' => DbDependency::className(),
        'sql' => 'SELECT COUNT(*) FROM post',
      ],
      'variations' => [
        \Yii::$app->language,
      ]
    ],
  ];
}


6.yii\filters\RateLimiter

RateLimiter 根据 漏桶算法 来实现速率限制。

7.yii\filters\VerbFilter

VerbFilter检查请求动作的HTTP请求方式是否允许执行,如果不允许,会抛出HTTP 405异常。 如下示例,VerbFilter指定CRUD动作所允许的请求方式。

use yii\filters\VerbFilter;

public function behaviors()
{
  return [
    'verbs' => [
      'class' => VerbFilter::className(),
      'actions' => [
        'index' => ['get'],
        'view'  => ['get'],
        'create' => ['get', 'post'],
        'update' => ['get', 'put', 'post'],
        'delete' => ['post', 'delete'],
      ],
    ],
  ];
}


8.yii\filters\Cors

跨域资源共享 CORS 机制允许一个网页的许多资源(例如字体、JavaScript等) 这些资源可以通过其他域名访问获取。 特别是JavaScript's AJAX 调用可使用 XMLHttpRequest 机制,由于同源安全策略该跨域请求会被网页浏览器禁止. CORS定义浏览器和服务器交互时哪些跨域请求允许和禁止。

yii\filters\Cors 应在 授权 / 认证 过滤器之前定义,以保证CORS头部被发送。

use yii\filters\Cors;
use yii\helpers\ArrayHelper;

public function behaviors()
{
  return ArrayHelper::merge([
    [
      'class' => Cors::className(),
    ],
  ], parent::behaviors());
}


Cors 可转为使用 cors 属性。

  • cors['Origin']: 定义允许来源的数组,可为['*'] (任何用户) 或 ['http://www.myserver.net', 'http://www.myotherserver.com']. 默认为 ['*'].
  • cors['Access-Control-Request-Method']: 允许动作数组如 ['GET', 'OPTIONS', 'HEAD']. 默认为 ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'].
  • cors['Access-Control-Request-Headers']: 允许请求头部数组,可为 ['*'] 所有类型头部 或 ['X-Request-With'] 指定类型头部. 默认为 ['*'].
  • cors['Access-Control-Allow-Credentials']: 定义当前请求是否使用证书,可为 true, false 或 null (不设置). 默认为null.
  • cors['Access-Control-Max-Age']: 定义请求的有效时间,默认为 86400.

例如,允许来源为 http://www.myserver.net 和方式为 GET, HEAD 和 OPTIONS 的CORS如下:

use yii\filters\Cors;
use yii\helpers\ArrayHelper;

public function behaviors()
{
  return ArrayHelper::merge([
    [
      'class' => Cors::className(),
      'cors' => [
        'Origin' => ['http://www.myserver.net'],
        'Access-Control-Request-Method' => ['GET', 'HEAD', 'OPTIONS'],
      ],
    ],
  ], parent::behaviors());
}


可以覆盖默认参数为每个动作调整CORS 头部。例如,为login动作增加Access-Control-Allow-Credentials参数如下所示:

use yii\filters\Cors;
use yii\helpers\ArrayHelper;

public function behaviors()
{
  return ArrayHelper::merge([
    [
      'class' => Cors::className(),
      'cors' => [
        'Origin' => ['http://www.myserver.net'],
        'Access-Control-Request-Method' => ['GET', 'HEAD', 'OPTIONS'],
      ],
      'actions' => [
        'login' => [
          'Access-Control-Allow-Credentials' => true,
        ]
      ]
    ],
  ], parent::behaviors());
}

Articles you may be interested in:

  • Introduction to some advanced usage of caching in PHP's Yii framework
  • In-depth analysis of the caching function in PHP's Yii framework
  • Advanced use of View in PHP's Yii framework
  • Detailed explanation of the methods of creating and rendering views in PHP's Yii framework
  • Study tutorial on Model model in PHP's Yii framework
  • Detailed explanation of the Controller controller in PHP's Yii framework
  • How to remove the behavior bound to a component in PHP's Yii framework
  • The definition and definition of behavior in PHP's Yii framework Explanation of binding methods
  • In-depth explanation of properties (Property) in PHP's Yii framework
  • Detailed explanation of the use of the front-end resource package that comes with PHP's Yii framework

www.bkjia.comtruehttp: //www.bkjia.com/PHPjc/1117067.htmlTechArticleA summary of the use of filters in PHP's Yii framework, yii filter Yii filter introduction A filter is a piece of code , can be configured to execute before or after the controller action is executed. For example, visit...
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn