欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

PHP的Yii框架中過(guò)濾器相關(guān)的使用總結(jié)

 更新時(shí)間:2016年03月29日 18:05:37   作者:秋風(fēng)澀  
這篇文章主要介紹了PHP的Yii框架中過(guò)濾器相關(guān)的使用總結(jié),文中列舉了一些常用的核心過(guò)濾器,需要的朋友可以參考下

Yii過(guò)濾器簡(jiǎn)介

過(guò)濾器是一段代碼,可被配置在控制器動(dòng)作執(zhí)行之前或之后執(zhí)行。例如, 訪問(wèn)控制過(guò)濾器將被執(zhí)行以確保在執(zhí)行請(qǐng)求的動(dòng)作之前用戶已通過(guò)身份驗(yàn)證;性能過(guò)濾器可用于測(cè)量控制器執(zhí)行所用的時(shí)間。

一個(gè)動(dòng)作可以有多個(gè)過(guò)濾器。過(guò)濾器執(zhí)行順序?yàn)樗鼈兂霈F(xiàn)在過(guò)濾器列表中的順序。過(guò)濾器可以阻止動(dòng)作及后面其他過(guò)濾器的執(zhí)行。

過(guò)濾器有兩種寫(xiě)法:

  • 基于方法的過(guò)濾器
  • 基于自定義過(guò)濾器類的過(guò)濾器

無(wú)論哪種過(guò)濾器,都必須在控制器中重寫(xiě)控制器的public function filters()方法,設(shè)置哪個(gè)過(guò)濾器對(duì)哪個(gè)動(dòng)作起作用。

基于方法的過(guò)濾器

編寫(xiě)基于方法的過(guò)濾器,要經(jīng)過(guò)三步:

在控制器中編寫(xiě)動(dòng)作(Action);
在控制器中編寫(xiě)過(guò)濾器函數(shù),函數(shù)名必須以filter為前綴,如:function filterAccessControl();
重寫(xiě)父類CController的filters()方法,定義過(guò)濾器與動(dòng)作的關(guān)系;
實(shí)例:

<?php 
   
  class UserController extends CController{ 
    ** 
     * 第一步:創(chuàng)建動(dòng)作 
     */ 
      function actionAdd(){  
        echo "actionAdd"; 
      } 
      /** 
      * 第二步:創(chuàng)建基于方法的過(guò)濾器 
       */ 
      public function filterAddFilter($filterChain) { 
        echo "基于方法的過(guò)濾器UserController.filterAdd<br>"; 
        $filterChain->run(); 
      } 
      /** 
      * 第三步:重寫(xiě)父類CController的filters()方法,定義過(guò)濾器與動(dòng)作的關(guān)系 
      * @see CController::filters() 
      */ 
      public function filters(){ 
        return array( 
      //定義過(guò)濾器與動(dòng)作的關(guān)聯(lián)關(guān)系 
          'addFilter + add', 
//         array( 
//             'application.filters.TestFilter',           
//         ), 
           
      ); 
    } 
  } 

自定義過(guò)濾器類

自定義過(guò)濾器類,需要單獨(dú)寫(xiě)一個(gè)過(guò)濾器類,并繼承CFilter類,重寫(xiě)CFilter類下的部分方法。大家可以看一下CFilter類的代碼,該類代碼不多,還是很容易看懂的。

自定義過(guò)濾器實(shí)例:

<?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>"; 
  } 
} 


在控制器中注冊(cè)該自定義過(guò)濾器與動(dòng)作的綁定關(guān)系:

/**
* 第三步:重寫(xiě)父類CController的filters()方法,定義過(guò)濾器與動(dòng)作的關(guān)系 
* @see CController::filters() 
*/ 
ublic function filters(){ 
return array( 
  //定義過(guò)濾器與動(dòng)作的關(guān)聯(lián)關(guān)系 
    'addFilter + add', 
      array( 
          'application.filters.TestFilter',           
      ), 
     
); 


我自定義了一個(gè)過(guò)濾器:TestFilter,繼承了CFilter類,重寫(xiě)了CFilter類的兩個(gè)主要方法:preFilter(前控制器,在動(dòng)作執(zhí)行前運(yùn)行)和postFilter(后控制器,在動(dòng)作執(zhí)行后運(yùn)行)。

兩種控制器的執(zhí)行順序

假設(shè)我將上面編寫(xiě)的自定義過(guò)濾器類與動(dòng)作actionAdd綁定,那么,自定義過(guò)濾器繼承自父類CFilter兩個(gè)方法:preFilter和postFilter,與綁定的actionAdd之間的執(zhí)行順序是怎樣的呢?

經(jīng)過(guò)試驗(yàn),執(zhí)行順序?yàn)椋篊Filter::preFilter--------->UserController::actionAdd--------->CFilter::postFilter。

也就是說(shuō),在動(dòng)作執(zhí)行前后都可以執(zhí)行過(guò)濾操作。

那么文章開(kāi)頭說(shuō)“過(guò)濾器可以阻止動(dòng)作及后面其他過(guò)濾器的執(zhí)行”是怎么做到的呢?

看了CFilter::preFilter的官方注釋就知道了:

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

CFilter::preFilter函數(shù)默認(rèn)return
 true;即,默認(rèn)執(zhí)行后面的動(dòng)作和后過(guò)濾器。如果在自定義過(guò)濾器類中,重寫(xiě)CFilter::preFilter方法,并return
 false;就可以阻止后面的動(dòng)作和過(guò)濾器執(zhí)行了!


使用過(guò)濾器

過(guò)濾器本質(zhì)上是一類特殊的 行為,所以使用過(guò)濾器和 使用 行為一樣。 可以在控制器類中覆蓋它的 yii\base\Controller::behaviors() 方法來(lái)申明過(guò)濾器,如下所示:

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');
      },
    ],
  ];
}

控制器類的過(guò)濾器默認(rèn)應(yīng)用到該類的 所有 動(dòng)作,你可以配置yii\base\ActionFilter::only屬性明確指定控制器應(yīng)用到哪些動(dòng)作。 在上述例子中,HttpCache 過(guò)濾器只應(yīng)用到index和view動(dòng)作。 也可以配置yii\base\ActionFilter::except屬性使一些動(dòng)作不執(zhí)行過(guò)濾器。

除了控制器外,可在 模塊或應(yīng)用主體 中申明過(guò)濾器。 申明之后,過(guò)濾器會(huì)應(yīng)用到所屬該模塊或應(yīng)用主體的 所有 控制器動(dòng)作, 除非像上述一樣配置過(guò)濾器的 yii\base\ActionFilter::only 和 yii\base\ActionFilter::except 屬性。

補(bǔ)充: 在模塊或應(yīng)用主體中申明過(guò)濾器,在yii\base\ActionFilter::only 和 yii\base\ActionFilter::except 屬性中使用路由 代替動(dòng)作ID, 因?yàn)樵谀K或應(yīng)用主體中只用動(dòng)作ID并不能唯一指定到具體動(dòng)作。.
當(dāng)一個(gè)動(dòng)作有多個(gè)過(guò)濾器時(shí),根據(jù)以下規(guī)則先后執(zhí)行:

預(yù)過(guò)濾

  • 按順序執(zhí)行應(yīng)用主體中behaviors()列出的過(guò)濾器。
  • 按順序執(zhí)行模塊中behaviors()列出的過(guò)濾器。
  • 按順序執(zhí)行控制器中behaviors()列出的過(guò)濾器。
  • 如果任意過(guò)濾器終止動(dòng)作執(zhí)行,后面的過(guò)濾器(包括預(yù)過(guò)濾和后過(guò)濾)不再執(zhí)行。
  • 成功通過(guò)預(yù)過(guò)濾后執(zhí)行動(dòng)作。

后過(guò)濾

  • 倒序執(zhí)行控制器中behaviors()列出的過(guò)濾器。
  • 倒序執(zhí)行模塊中behaviors()列出的過(guò)濾器。
  • 倒序執(zhí)行應(yīng)用主體中behaviors()列出的過(guò)濾器。

創(chuàng)建過(guò)濾器

繼承 yii\base\ActionFilter 類并覆蓋 yii\base\ActionFilter::beforeAction() 和/或 yii\base\ActionFilter::afterAction() 方法來(lái)創(chuàng)建動(dòng)作的過(guò)濾器,前者在動(dòng)作執(zhí)行之前執(zhí)行,后者在動(dòng)作執(zhí)行之后執(zhí)行。 yii\base\ActionFilter::beforeAction() 返回值決定動(dòng)作是否應(yīng)該執(zhí)行, 如果為false,之后的過(guò)濾器和動(dòng)作不會(huì)繼續(xù)執(zhí)行。

下面的例子申明一個(gè)記錄動(dòng)作執(zhí)行時(shí)間日志的過(guò)濾器。

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);
  }
}


核心過(guò)濾器

Yii提供了一組常用過(guò)濾器,在yii\filters命名空間下,接下來(lái)我們簡(jiǎn)要介紹這些過(guò)濾器。

1.yii\filters\AccessControl

AccessControl提供基于yii\filters\AccessControl::rules規(guī)則的訪問(wèn)控制。 特別是在動(dòng)作執(zhí)行之前,訪問(wèn)控制會(huì)檢測(cè)所有規(guī)則并找到第一個(gè)符合上下文的變量(比如用戶IP地址、登錄狀態(tài)等等)的規(guī)則, 來(lái)決定允許還是拒絕請(qǐng)求動(dòng)作的執(zhí)行,如果沒(méi)有規(guī)則符合,訪問(wèn)就會(huì)被拒絕。

如下示例表示表示允許已認(rèn)證用戶訪問(wèn)create 和 update 動(dòng)作,拒絕其他用戶訪問(wèn)這兩個(gè)動(dòng)作。

use yii\filters\AccessControl;

public function behaviors()
{
  return [
    'access' => [
      'class' => AccessControl::className(),
      'only' => ['create', 'update'],
      'rules' => [
        // 允許認(rèn)證用戶
        [
          'allow' => true,
          'roles' => ['@'],
        ],
        // 默認(rèn)禁止其他用戶
      ],
    ],
  ];
}


2.認(rèn)證方法過(guò)濾器

認(rèn)證方法過(guò)濾器通過(guò)HTTP Basic Auth或OAuth 2 來(lái)認(rèn)證一個(gè)用戶,認(rèn)證方法過(guò)濾器類在 yii\filters\auth 命名空間下。

如下示例表示可使用yii\filters\auth\HttpBasicAuth來(lái)認(rèn)證一個(gè)用戶,它使用基于HTTP基礎(chǔ)認(rèn)證方法的令牌。 注意為了可運(yùn)行,yii\web\User::identityClass 類必須 實(shí)現(xiàn) yii\web\IdentityInterface::findIdentityByAccessToken()方法。

use yii\filters\auth\HttpBasicAuth;

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

認(rèn)證方法過(guò)濾器通常在實(shí)現(xiàn)RESTful API中使用。

3.yii\filters\ContentNegotiator

ContentNegotiator支持響應(yīng)內(nèi)容格式處理和語(yǔ)言處理。 通過(guò)檢查 GET 參數(shù)和 Accept HTTP頭部來(lái)決定響應(yīng)內(nèi)容格式和語(yǔ)言。

如下示例,配置ContentNegotiator支持JSON和XML響應(yīng)格式和英語(yǔ)(美國(guó))和德語(yǔ)。

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',
      ],
    ],
  ];
}


在應(yīng)用主體生命周期過(guò)程中檢測(cè)響應(yīng)格式和語(yǔ)言簡(jiǎn)單很多, 因此ContentNegotiator設(shè)計(jì)可被引導(dǎo)啟動(dòng)組件調(diào)用的過(guò)濾器。 如下例所示可以將它配置在應(yīng)用主體配置。

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',
      ],
    ],
  ],
];


補(bǔ)充: 如果請(qǐng)求中沒(méi)有檢測(cè)到內(nèi)容格式和語(yǔ)言,使用formats和languages第一個(gè)配置項(xiàng)。
4.yii\filters\HttpCache

HttpCache利用Last-Modified 和 Etag HTTP頭實(shí)現(xiàn)客戶端緩存。例如:

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實(shí)現(xiàn)服務(wù)器端整個(gè)頁(yè)面的緩存。如下示例所示,PageCache應(yīng)用在index動(dòng)作, 緩存整個(gè)頁(yè)面60秒或post表的記錄數(shù)發(fā)生變化。它也會(huì)根據(jù)不同應(yīng)用語(yǔ)言保存不同的頁(yè)面版本。

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 根據(jù) 漏桶算法 來(lái)實(shí)現(xiàn)速率限制。

7.yii\filters\VerbFilter

VerbFilter檢查請(qǐng)求動(dòng)作的HTTP請(qǐng)求方式是否允許執(zhí)行,如果不允許,會(huì)拋出HTTP 405異常。 如下示例,VerbFilter指定CRUD動(dòng)作所允許的請(qǐng)求方式。

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 機(jī)制允許一個(gè)網(wǎng)頁(yè)的許多資源(例如字體、JavaScript等) 這些資源可以通過(guò)其他域名訪問(wèn)獲取。 特別是JavaScript's AJAX 調(diào)用可使用 XMLHttpRequest 機(jī)制,由于同源安全策略該跨域請(qǐng)求會(huì)被網(wǎng)頁(yè)瀏覽器禁止. CORS定義瀏覽器和服務(wù)器交互時(shí)哪些跨域請(qǐng)求允許和禁止。

yii\filters\Cors 應(yīng)在 授權(quán) / 認(rèn)證 過(guò)濾器之前定義,以保證CORS頭部被發(fā)送。

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

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


Cors 可轉(zhuǎn)為使用 cors 屬性。

  • cors['Origin']: 定義允許來(lái)源的數(shù)組,可為['*'] (任何用戶) 或 ['http://www.myserver.net', 'http://www.myotherserver.com']. 默認(rèn)為 ['*'].
  • cors['Access-Control-Request-Method']: 允許動(dòng)作數(shù)組如 ['GET', 'OPTIONS', 'HEAD']. 默認(rèn)為 ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'].
  • cors['Access-Control-Request-Headers']: 允許請(qǐng)求頭部數(shù)組,可為 ['*'] 所有類型頭部 或 ['X-Request-With'] 指定類型頭部. 默認(rèn)為 ['*'].
  • cors['Access-Control-Allow-Credentials']: 定義當(dāng)前請(qǐng)求是否使用證書(shū),可為 true, false 或 null (不設(shè)置). 默認(rèn)為null.
  • cors['Access-Control-Max-Age']: 定義請(qǐng)求的有效時(shí)間,默認(rèn)為 86400.

例如,允許來(lái)源為 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());
}


可以覆蓋默認(rèn)參數(shù)為每個(gè)動(dòng)作調(diào)整CORS 頭部。例如,為login動(dòng)作增加Access-Control-Allow-Credentials參數(shù)如下所示:

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());
}

相關(guān)文章

最新評(píng)論