《PHP學(xué)習(xí):PHP的Yii框架中過濾器相關(guān)的使用總結(jié)》要點:
本文介紹了PHP學(xué)習(xí):PHP的Yii框架中過濾器相關(guān)的使用總結(jié),希望對您有用。如果有疑問,可以聯(lián)系我們。
相關(guān)主題:YII框架
Yii過濾器簡介PHP實例
過濾器是一段代碼,可被配置在控制器動作執(zhí)行之前或之后執(zhí)行.例如, 訪問控制過濾器將被執(zhí)行以確保在執(zhí)行請求的動作之前用戶已通過身份驗證;性能過濾器可用于測量控制器執(zhí)行所用的時間.PHP實例
一個動作可以有多個過濾器.過濾器執(zhí)行順序為它們出現(xiàn)在過濾器列表中的順序.過濾器可以阻止動作及后面其他過濾器的執(zhí)行.PHP實例
過濾器有兩種寫法:PHP實例
無論哪種過濾器,都必須在控制器中重寫控制器的public function filters()方法,設(shè)置哪個過濾器對哪個動作起作用.PHP實例
基于方法的過濾器PHP實例
編寫基于方法的過濾器,要經(jīng)過三步:PHP實例
在控制器中編寫動作(Action);
在控制器中編寫過濾器函數(shù),函數(shù)名必須以filter為前綴,如:function filterAccessControl();
重寫父類CController的filters()方法,定義過濾器與動作的關(guān)系;
實例:PHP實例
<?php class UserController extends CController{ ** * 第一步:創(chuàng)建動作 */ function actionAdd(){ echo "actionAdd"; } /** * 第二步:創(chuàng)建基于方法的過濾器 */ public function filterAddFilter($filterChain) { echo "基于方法的過濾器UserController.filterAdd<br>"; $filterChain->run(); } /** * 第三步:重寫父類CController的filters()方法,定義過濾器與動作的關(guān)系 * @see CController::filters() */ public function filters(){ return array( //定義過濾器與動作的關(guān)聯(lián)關(guān)系 'addFilter + add', // array( // 'application.filters.TestFilter', // ), ); } }
自定義過濾器類PHP實例
自定義過濾器類,需要單獨寫一個過濾器類,并繼承CFilter類,重寫CFilter類下的部分方法.大家可以看一下CFilter類的代碼,該類代碼不多,還是很容易看懂的.PHP實例
自定義過濾器實例:PHP實例
<?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>"; } }
在控制器中注冊該自定義過濾器與動作的綁定關(guān)系:PHP實例
/** * 第三步:重寫父類CController的filters()方法,定義過濾器與動作的關(guān)系 * @see CController::filters() */ ublic function filters(){ return array( //定義過濾器與動作的關(guān)聯(lián)關(guān)系 'addFilter + add', array( 'application.filters.TestFilter', ), );
我自定義了一個過濾器:TestFilter,繼承了CFilter類,重寫了CFilter類的兩個主要方法:preFilter(前控制器,在動作執(zhí)行前運(yùn)行)和postFilter(后控制器,在動作執(zhí)行后運(yùn)行).PHP實例
兩種控制器的執(zhí)行順序 PHP實例
假設(shè)我將上面編寫的自定義過濾器類與動作actionAdd綁定,那么,自定義過濾器繼承自父類CFilter兩個方法:preFilter和postFilter,與綁定的actionAdd之間的執(zhí)行順序是怎樣的呢?PHP實例
經(jīng)過試驗,執(zhí)行順序為:CFilter::preFilter--------->UserController::actionAdd--------->CFilter::postFilter.PHP實例
也就是說,在動作執(zhí)行前后都可以執(zhí)行過濾操作.PHP實例
那么文章開頭說“過濾器可以阻止動作及后面其他過濾器的執(zhí)行”是怎么做到的呢?PHP實例
看了CFilter::preFilter的官方注釋就知道了:PHP實例
@return boolean whether the filtering process should continue and the action should be executed.
PHP實例
CFilter::preFilter函數(shù)默認(rèn)return
?true;即,默認(rèn)執(zhí)行后面的動作和后過濾器.如果在自定義過濾器類中,重寫CFilter::preFilter方法,并return
?false;就可以阻止后面的動作和過濾器執(zhí)行了!PHP實例
使用過濾器PHP實例
過濾器本質(zhì)上是一類特殊的 行為,所以使用過濾器和 使用 行為一樣. 可以在控制器類中覆蓋它的 yii\base\Controller::behaviors() 方法來申明過濾器,如下所示:PHP實例
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'); }, ], ]; }
控制器類的過濾器默認(rèn)應(yīng)用到該類的 所有 動作,你可以配置yii\base\ActionFilter::only屬性明確指定控制器應(yīng)用到哪些動作. 在上述例子中,HttpCache 過濾器只應(yīng)用到index和view動作. 也可以配置yii\base\ActionFilter::except屬性使一些動作不執(zhí)行過濾器.PHP實例
除了控制器外,可在 模塊或應(yīng)用主體 中申明過濾器. 申明之后,過濾器會應(yīng)用到所屬該模塊或應(yīng)用主體的 所有 控制器動作, 除非像上述一樣配置過濾器的 yii\base\ActionFilter::only 和 yii\base\ActionFilter::except 屬性.PHP實例
補(bǔ)充: 在模塊或應(yīng)用主體中申明過濾器,在yii\base\ActionFilter::only 和 yii\base\ActionFilter::except 屬性中使用路由 代替動作ID, 因為在模塊或應(yīng)用主體中只用動作ID并不能唯一指定到具體動作..
當(dāng)一個動作有多個過濾器時,根據(jù)以下規(guī)則先后執(zhí)行:PHP實例
預(yù)過濾PHP實例
后過濾PHP實例
創(chuàng)建過濾器PHP實例
繼承 yii\base\ActionFilter 類并覆蓋 yii\base\ActionFilter::beforeAction() 和/或 yii\base\ActionFilter::afterAction() 方法來創(chuàng)建動作的過濾器,前者在動作執(zhí)行之前執(zhí)行,后者在動作執(zhí)行之后執(zhí)行. yii\base\ActionFilter::beforeAction() 返回值決定動作是否應(yīng)該執(zhí)行, 如果為false,之后的過濾器和動作不會繼續(xù)執(zhí)行.PHP實例
下面的例子申明一個記錄動作執(zhí)行時間日志的過濾器.PHP實例
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); } }
核心過濾器PHP實例
Yii提供了一組常用過濾器,在yii\filters命名空間下,接下來我們簡要介紹這些過濾器.PHP實例
1.yii\filters\AccessControlPHP實例
AccessControl提供基于yii\filters\AccessControl::rules規(guī)則的訪問控制. 特別是在動作執(zhí)行之前,訪問控制會檢測所有規(guī)則并找到第一個符合上下文的變量(比如用戶IP地址、登錄狀態(tài)等等)的規(guī)則, 來決定允許還是拒絕請求動作的執(zhí)行,如果沒有規(guī)則符合,訪問就會被拒絕.PHP實例
如下示例表示表示允許已認(rèn)證用戶訪問create 和 update 動作,拒絕其他用戶訪問這兩個動作.PHP實例
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)證方法過濾器PHP實例
認(rèn)證方法過濾器通過HTTP Basic Auth或OAuth 2 來認(rèn)證一個用戶,認(rèn)證方法過濾器類在 yii\filters\auth 命名空間下.PHP實例
如下示例表示可使用yii\filters\auth\HttpBasicAuth來認(rèn)證一個用戶,它使用基于HTTP基礎(chǔ)認(rèn)證方法的令牌. 注意為了可運(yùn)行,yii\web\User::identityClass 類必須 實現(xiàn) yii\web\IdentityInterface::findIdentityByAccessToken()方法.PHP實例
use yii\filters\auth\HttpBasicAuth; public function behaviors() { return [ 'basicAuth' => [ 'class' => HttpBasicAuth::className(), ], ]; }
認(rèn)證方法過濾器通常在實現(xiàn)RESTful API中使用.PHP實例
3.yii\filters\ContentNegotiatorPHP實例
ContentNegotiator支持響應(yīng)內(nèi)容格式處理和語言處理. 通過檢查 GET 參數(shù)和 Accept HTTP頭部來決定響應(yīng)內(nèi)容格式和語言.PHP實例
如下示例,配置ContentNegotiator支持JSON和XML響應(yīng)格式和英語(美國)和德語.PHP實例
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)用主體生命周期過程中檢測響應(yīng)格式和語言簡單很多, 因此ContentNegotiator設(shè)計可被引導(dǎo)啟動組件調(diào)用的過濾器. 如下例所示可以將它配置在應(yīng)用主體配置.PHP實例
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ǔ)充: 如果請求中沒有檢測到內(nèi)容格式和語言,使用formats和languages第一個配置項.
4.yii\filters\HttpCachePHP實例
HttpCache利用Last-Modified 和 Etag HTTP頭實現(xiàn)客戶端緩存.例如:PHP實例
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\PageCachePHP實例
PageCache實現(xiàn)服務(wù)器端整個頁面的緩存.如下示例所示,PageCache應(yīng)用在index動作, 緩存整個頁面60秒或post表的記錄數(shù)發(fā)生變化.它也會根據(jù)不同應(yīng)用語言保存不同的頁面版本.PHP實例
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\RateLimiterPHP實例
RateLimiter 根據(jù) 漏桶算法 來實現(xiàn)速率限制.PHP實例
7.yii\filters\VerbFilterPHP實例
VerbFilter檢查請求動作的HTTP請求方式是否允許執(zhí)行,如果不允許,會拋出HTTP 405異常. 如下示例,VerbFilter指定CRUD動作所允許的請求方式.PHP實例
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\CorsPHP實例
跨域資源共享 CORS 機(jī)制允許一個網(wǎng)頁的許多資源(例如字體、JavaScript等) 這些資源可以通過其他域名訪問獲取. 特別是JavaScript's AJAX 調(diào)用可使用 XMLHttpRequest 機(jī)制,由于同源安全策略該跨域請求會被網(wǎng)頁瀏覽器禁止. CORS定義瀏覽器和服務(wù)器交互時哪些跨域請求允許和禁止.PHP實例
yii\filters\Cors 應(yīng)在 授權(quán) / 認(rèn)證 過濾器之前定義,以保證CORS頭部被發(fā)送.PHP實例
use yii\filters\Cors; use yii\helpers\ArrayHelper; public function behaviors() { return ArrayHelper::merge([ [ 'class' => Cors::className(), ], ], parent::behaviors()); }
Cors 可轉(zhuǎn)為使用 cors 屬性.PHP實例
例如,允許來源為 http://www.myserver.net 和方式為 GET, HEAD 和 OPTIONS 的CORS如下:PHP實例
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ù)為每個動作調(diào)整CORS 頭部.例如,為login動作增加Access-Control-Allow-Credentials參數(shù)如下所示:PHP實例
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()); }
維易PHP培訓(xùn)學(xué)院每天發(fā)布《PHP學(xué)習(xí):PHP的Yii框架中過濾器相關(guān)的使用總結(jié)》等實戰(zhàn)技能,PHP、MYSQL、LINUX、APP、JS,CSS全面培養(yǎng)人才。
轉(zhuǎn)載請注明本頁網(wǎng)址:
http://www.fzlkiss.com/jiaocheng/7015.html