1 位追蹤者

類別 yii\filters\RateLimiter

繼承關係yii\filters\RateLimiter » yii\base\ActionFilter » yii\base\Behavior » yii\base\BaseObject
實作yii\base\Configurable
自版本起可用2.0
原始碼 https://github.com/yiisoft/yii2/blob/master/framework/filters/RateLimiter.php

RateLimiter 實作了基於 漏桶演算法 的速率限制演算法。

您可以透過將 RateLimiter 作為行為附加到控制器或模組來使用,如下所示:

public function behaviors()
{
    return [
        'rateLimiter' => [
            'class' => \yii\filters\RateLimiter::class,
        ],
    ];
}

當使用者超出其速率限制時,RateLimiter 將拋出 yii\web\TooManyRequestsHttpException 異常。

請注意,RateLimiter 需要 $user 實作 yii\filters\RateLimitInterface。如果 $user 未設定或未實作 yii\filters\RateLimitInterface,RateLimiter 將不會執行任何操作。

公開屬性

隱藏繼承的屬性

屬性 類型 描述 定義於
$enableRateLimitHeaders boolean 是否在回應中包含速率限制標頭 yii\filters\RateLimiter
$errorMessage string 當超出速率限制時要顯示的訊息 yii\filters\RateLimiter
$except array 此篩選器不應應用於的動作 ID 清單。 yii\base\ActionFilter
$only array 此篩選器應應用於的動作 ID 清單。 yii\base\ActionFilter
$owner yii\base\Component|null 此行為的擁有者 yii\base\Behavior
$request yii\web\Request|null 當前請求。 yii\filters\RateLimiter
$response yii\web\Response|null 要發送的回應。 yii\filters\RateLimiter
$user yii\filters\RateLimitInterface|Closure|null 實作 RateLimitInterface 的使用者物件。 yii\filters\RateLimiter

公開方法

隱藏繼承的方法

方法 描述 定義於
__call() 調用未作為類別方法的具名方法。 yii\base\BaseObject
__construct() 建構子。 yii\base\BaseObject
__get() 傳回物件屬性的值。 yii\base\BaseObject
__isset() 檢查屬性是否已設定,即已定義且非 null。 yii\base\BaseObject
__set() 設定物件屬性的值。 yii\base\BaseObject
__unset() 將物件屬性設定為 null。 yii\base\BaseObject
addRateLimitHeaders() 將速率限制標頭新增至回應。 yii\filters\RateLimiter
afterAction() 此方法在動作執行後立即調用。 yii\base\ActionFilter
afterFilter() yii\base\ActionFilter
attach() 將行為物件附加到元件。 yii\base\ActionFilter
beforeAction() 此方法在動作即將執行之前調用(在所有可能的篩選器之後)。您可以覆寫此方法以執行動作的最後一分鐘準備。 yii\filters\RateLimiter
beforeFilter() yii\base\ActionFilter
canGetProperty() 傳回一個值,指示是否可以讀取屬性。 yii\base\BaseObject
canSetProperty() 傳回一個值,指示是否可以設定屬性。 yii\base\BaseObject
checkRateLimit() 檢查速率限制是否超出。 yii\filters\RateLimiter
className() 傳回此類別的完整限定名稱。 yii\base\BaseObject
detach() 從元件分離行為物件。 yii\base\ActionFilter
events() 宣告 $owner 的事件處理器。 yii\base\Behavior
hasMethod() 傳回值,指示是否已定義方法。 yii\base\BaseObject
hasProperty() 傳回值,指示是否已定義屬性。 yii\base\BaseObject
init() 初始化物件。 yii\filters\RateLimiter

Protected Methods

隱藏繼承的方法

方法 描述 定義於
getActionId() 傳回動作 ID,方法是將 yii\base\Action::$uniqueId 轉換為相對於模組的 ID。 yii\base\ActionFilter
isActive() 傳回值,指示篩選器是否對給定的動作處於活動狀態。 yii\base\ActionFilter

Property Details

隱藏繼承的屬性

$enableRateLimitHeaders public property

是否在回應中包含速率限制標頭

$errorMessage public property

當超出速率限制時要顯示的訊息

public string $errorMessage 'Rate limit exceeded.'
$request public property

目前的請求。如果未設定,將使用 request 應用程式組件。

$response public property

要傳送的回應。如果未設定,將使用 response 應用程式組件。

$user public property

實作 RateLimitInterface 的使用者物件。如果未設定,則會採用 Yii::$app->user->getIdentity(false) 的值。 {@since 2.0.38} 可以提供閉包函式,以便在執行階段指派使用者身分。當您使用標準 Yii::$app->user 組件時,建議使用閉包來指派使用者身分。請參閱以下範例: `php 'user' => function() {

return Yii::$app->apiUser->identity;

} `

Method Details

隱藏繼承的方法

__call() public method

Defined in: yii\base\BaseObject::__call()

調用未作為類別方法的具名方法。

請勿直接呼叫此方法,因為它是 PHP 魔術方法,當呼叫未知的函式時,將會隱含地呼叫此方法。

public mixed __call ( $name, $params )
$name string

方法名稱

$params array

方法參數

return mixed

方法傳回值

throws yii\base\UnknownMethodException

當呼叫未知方法時

                public function __call($name, $params)
{
    throw new UnknownMethodException('Calling unknown method: ' . get_class($this) . "::$name()");
}

            
__construct() public method

Defined in: yii\base\BaseObject::__construct()

建構子。

預設實作會執行兩件事

  • 使用給定的組態 $config 初始化物件。
  • 呼叫 init()

如果子類別中覆寫了此方法,建議

  • 建構子的最後一個參數是組態陣列,例如此處的 $config
  • 在建構子的結尾呼叫父類別實作。
public void __construct ( $config = [] )
$config array

將用於初始化物件屬性的名稱-值配對

                public function __construct($config = [])
{
    if (!empty($config)) {
        Yii::configure($this, $config);
    }
    $this->init();
}

            
__get() public method

Defined in: yii\base\BaseObject::__get()

傳回物件屬性的值。

請勿直接呼叫此方法,因為它是 PHP 魔術方法,當執行 $value = $object->property; 時,將會隱含地呼叫此方法。

另請參閱 __set()

public mixed __get ( $name )
$name string

屬性名稱

return mixed

屬性值

throws yii\base\UnknownPropertyException

如果未定義屬性

throws yii\base\InvalidCallException

如果屬性為唯寫

                public function __get($name)
{
    $getter = 'get' . $name;
    if (method_exists($this, $getter)) {
        return $this->$getter();
    } elseif (method_exists($this, 'set' . $name)) {
        throw new InvalidCallException('Getting write-only property: ' . get_class($this) . '::' . $name);
    }
    throw new UnknownPropertyException('Getting unknown property: ' . get_class($this) . '::' . $name);
}

            
__isset() public method

Defined in: yii\base\BaseObject::__isset()

檢查屬性是否已設定,即已定義且非 null。

請勿直接呼叫此方法,因為它是 PHP 魔術方法,當執行 isset($object->property) 時,將會隱含地呼叫此方法。

請注意,如果未定義屬性,將傳回 false。

另請參閱 https://php.dev.org.tw/manual/en/function.isset.php

public boolean __isset ( $name )
$name string

屬性名稱或事件名稱

return boolean

具名屬性是否已設定 (非 null)。

                public function __isset($name)
{
    $getter = 'get' . $name;
    if (method_exists($this, $getter)) {
        return $this->$getter() !== null;
    }
    return false;
}

            
__set() public method

Defined in: yii\base\BaseObject::__set()

設定物件屬性的值。

請勿直接呼叫此方法,因為它是 PHP 魔術方法,當執行 $object->property = $value; 時,將會隱含地呼叫此方法。

另請參閱 __get()

public void __set ( $name, $value )
$name string

屬性名稱或事件名稱

$value mixed

屬性值

throws yii\base\UnknownPropertyException

如果未定義屬性

throws yii\base\InvalidCallException

如果屬性為唯讀

                public function __set($name, $value)
{
    $setter = 'set' . $name;
    if (method_exists($this, $setter)) {
        $this->$setter($value);
    } elseif (method_exists($this, 'get' . $name)) {
        throw new InvalidCallException('Setting read-only property: ' . get_class($this) . '::' . $name);
    } else {
        throw new UnknownPropertyException('Setting unknown property: ' . get_class($this) . '::' . $name);
    }
}

            
__unset() public method

Defined in: yii\base\BaseObject::__unset()

將物件屬性設定為 null。

請勿直接呼叫此方法,因為它是 PHP 魔術方法,當執行 unset($object->property) 時,將會隱含地呼叫此方法。

請注意,如果未定義屬性,此方法將不會執行任何動作。如果屬性為唯讀,則會擲回例外。

另請參閱 https://php.dev.org.tw/manual/en/function.unset.php

public void __unset ( $name )
$name string

屬性名稱

throws yii\base\InvalidCallException

如果屬性為唯讀。

                public function __unset($name)
{
    $setter = 'set' . $name;
    if (method_exists($this, $setter)) {
        $this->$setter(null);
    } elseif (method_exists($this, 'get' . $name)) {
        throw new InvalidCallException('Unsetting read-only property: ' . get_class($this) . '::' . $name);
    }
}

            
addRateLimitHeaders() public method

將速率限制標頭新增至回應。

public void addRateLimitHeaders ( $response, $limit, $remaining, $reset )
$response yii\web\Response
$limit integer

在一段期間內允許的最大請求數

$remaining integer

在目前期間內剩餘的允許請求數

$reset integer

在再次擁有最大允許請求數之前要等待的秒數

                public function addRateLimitHeaders($response, $limit, $remaining, $reset)
{
    if ($this->enableRateLimitHeaders) {
        $response->getHeaders()
            ->set('X-Rate-Limit-Limit', $limit)
            ->set('X-Rate-Limit-Remaining', $remaining)
            ->set('X-Rate-Limit-Reset', $reset);
    }
}

            
afterAction() public method

Defined in: yii\base\ActionFilter::afterAction()

此方法在動作執行後立即調用。

您可以覆寫此方法,為動作執行一些後處理。

public mixed afterAction ( $action, $result )
$action yii\base\Action

剛執行的動作。

$result mixed

動作執行結果

return mixed

已處理的動作結果。

                public function afterAction($action, $result)
{
    return $result;
}

            
afterFilter() public method
public void afterFilter ( $event )
$event yii\base\ActionEvent

                public function afterFilter($event)
{
    $event->result = $this->afterAction($event->action, $event->result);
    $this->owner->off(Controller::EVENT_AFTER_ACTION, [$this, 'afterFilter']);
}

            
attach() public method

Defined in: yii\base\ActionFilter::attach()

將行為物件附加到元件。

預設實作將設定 $owner 屬性,並附加在 events() 中宣告的事件處理器。如果您覆寫此方法,請務必呼叫父類別實作。

public void attach ( $owner )
$owner yii\base\Component

要附加此行為的組件。

                public function attach($owner)
{
    $this->owner = $owner;
    $owner->on(Controller::EVENT_BEFORE_ACTION, [$this, 'beforeFilter']);
}

            
beforeAction() public method

此方法在動作即將執行之前調用(在所有可能的篩選器之後)。您可以覆寫此方法以執行動作的最後一分鐘準備。

public boolean beforeAction ( $action )
$action yii\base\Action

要執行的動作。

return boolean

是否應繼續執行動作。

                public function beforeAction($action)
{
    if ($this->user === null && Yii::$app->getUser()) {
        $this->user = Yii::$app->getUser()->getIdentity(false);
    }
    if ($this->user instanceof Closure) {
        $this->user = call_user_func($this->user, $action);
    }
    if ($this->user instanceof RateLimitInterface) {
        Yii::debug('Check rate limit', __METHOD__);
        $this->checkRateLimit($this->user, $this->request, $this->response, $action);
    } elseif ($this->user) {
        Yii::info('Rate limit skipped: "user" does not implement RateLimitInterface.', __METHOD__);
    } else {
        Yii::info('Rate limit skipped: user not logged in.', __METHOD__);
    }
    return true;
}

            
beforeFilter() public method
public void beforeFilter ( $event )
$event yii\base\ActionEvent

                public function beforeFilter($event)
{
    if (!$this->isActive($event->action)) {
        return;
    }
    $event->isValid = $this->beforeAction($event->action);
    if ($event->isValid) {
        // call afterFilter only if beforeFilter succeeds
        // beforeFilter and afterFilter should be properly nested
        $this->owner->on(Controller::EVENT_AFTER_ACTION, [$this, 'afterFilter'], null, false);
    } else {
        $event->handled = true;
    }
}

            
canGetProperty() public method

Defined in: yii\base\BaseObject::canGetProperty()

傳回一個值,指示是否可以讀取屬性。

如果符合以下條件,則屬性為可讀取:

  • 類別具有與指定名稱相關聯的 getter 方法 (在這種情況下,屬性名稱不區分大小寫);
  • 類別具有具有指定名稱的成員變數 (當 $checkVars 為 true 時);

另請參閱 canSetProperty()

public boolean canGetProperty ( $name, $checkVars true )
$name string

屬性名稱

$checkVars boolean

是否將成員變數視為屬性

return boolean

屬性是否可讀取

                public function canGetProperty($name, $checkVars = true)
{
    return method_exists($this, 'get' . $name) || $checkVars && property_exists($this, $name);
}

            
canSetProperty() public method

Defined in: yii\base\BaseObject::canSetProperty()

傳回一個值,指示是否可以設定屬性。

如果符合以下條件,則屬性為可寫入:

  • 類別具有與指定名稱相關聯的 setter 方法 (在這種情況下,屬性名稱不區分大小寫);
  • 類別具有具有指定名稱的成員變數 (當 $checkVars 為 true 時);

另請參閱 canGetProperty()

public boolean canSetProperty ( $name, $checkVars true )
$name string

屬性名稱

$checkVars boolean

是否將成員變數視為屬性

return boolean

屬性是否可寫入

                public function canSetProperty($name, $checkVars = true)
{
    return method_exists($this, 'set' . $name) || $checkVars && property_exists($this, $name);
}

            
checkRateLimit() public method

檢查速率限制是否超出。

public void checkRateLimit ( $user, $request, $response, $action )
$user yii\filters\RateLimitInterface

目前的用戶

$request yii\web\Request
$response yii\web\Response
$action yii\base\Action

要執行的動作

throws yii\web\TooManyRequestsHttpException

如果超出速率限制

                public function checkRateLimit($user, $request, $response, $action)
{
    list($limit, $window) = $user->getRateLimit($request, $action);
    list($allowance, $timestamp) = $user->loadAllowance($request, $action);
    $current = time();
    $allowance += (int) (($current - $timestamp) * $limit / $window);
    if ($allowance > $limit) {
        $allowance = $limit;
    }
    if ($allowance < 1) {
        $user->saveAllowance($request, $action, 0, $current);
        $this->addRateLimitHeaders($response, $limit, 0, $window);
        throw new TooManyRequestsHttpException($this->errorMessage);
    }
    $user->saveAllowance($request, $action, $allowance - 1, $current);
    $this->addRateLimitHeaders($response, $limit, $allowance - 1, (int) (($limit - $allowance + 1) * $window / $limit));
}

            
className() public static method
自 2.0.14 版本起已過時。在 PHP >=5.5 上,請改用 ::class

Defined in: yii\base\BaseObject::className()

傳回此類別的完整限定名稱。

public static string className ( )
return string

此類別的完整限定名稱。

                public static function className()
{
    return get_called_class();
}

            
detach() public method

Defined in: yii\base\ActionFilter::detach()

從元件分離行為物件。

預設實作將取消設定 $owner 屬性,並分離在 events() 中宣告的事件處理器。如果您覆寫此方法,請務必呼叫父類別實作。

public void detach ( )

                public function detach()
{
    if ($this->owner) {
        $this->owner->off(Controller::EVENT_BEFORE_ACTION, [$this, 'beforeFilter']);
        $this->owner->off(Controller::EVENT_AFTER_ACTION, [$this, 'afterFilter']);
        $this->owner = null;
    }
}

            
events() public method

Defined in: yii\base\Behavior::events()

宣告 $owner 的事件處理器。

子類別可以覆寫此方法,以宣告應附加到 $owner 組件事件的 PHP 回呼。

當行為附加到擁有者時,回呼將附加到 $owner 的事件;當行為從組件分離時,回呼將從事件中分離。

回呼可以是下列任何一種

  • 此行為中的方法:'handleClick',相當於 [$this, 'handleClick']
  • 物件方法:[$object, 'handleClick']
  • 靜態方法:['Page', 'handleClick']
  • 匿名函式:function ($event) { ... }

以下為範例

[
    Model::EVENT_BEFORE_VALIDATE => 'myBeforeValidate',
    Model::EVENT_AFTER_VALIDATE => 'myAfterValidate',
]
public array events ( )
return array

事件 (陣列鍵) 和對應的事件處理器方法 (陣列值)。

                public function events()
{
    return [];
}

            
getActionId() protected method (available since version 2.0.7)

Defined in: yii\base\ActionFilter::getActionId()

傳回動作 ID,方法是將 yii\base\Action::$uniqueId 轉換為相對於模組的 ID。

protected string getActionId ( $action )
$action yii\base\Action

                protected function getActionId($action)
{
    if ($this->owner instanceof Module) {
        $mid = $this->owner->getUniqueId();
        $id = $action->getUniqueId();
        if ($mid !== '' && strpos($id, $mid) === 0) {
            $id = substr($id, strlen($mid) + 1);
        }
    } else {
        $id = $action->id;
    }
    return $id;
}

            
hasMethod() public method

Defined in: yii\base\BaseObject::hasMethod()

傳回值,指示是否已定義方法。

預設實作是對 php 函式 method_exists() 的呼叫。當您實作 php 魔術方法 __call() 時,可以覆寫此方法。

public boolean hasMethod ( $name )
$name string

方法名稱

return boolean

方法是否已定義

                public function hasMethod($name)
{
    return method_exists($this, $name);
}

            
hasProperty() public method

Defined in: yii\base\BaseObject::hasProperty()

傳回值,指示是否已定義屬性。

如果符合以下條件,則屬性已定義:

  • 類別具有與指定名稱相關聯的 getter 或 setter 方法 (在這種情況下,屬性名稱不區分大小寫);
  • 類別具有具有指定名稱的成員變數 (當 $checkVars 為 true 時);

另請參閱

public boolean hasProperty ( $name, $checkVars true )
$name string

屬性名稱

$checkVars boolean

是否將成員變數視為屬性

return boolean

屬性是否已定義

                public function hasProperty($name, $checkVars = true)
{
    return $this->canGetProperty($name, $checkVars) || $this->canSetProperty($name, false);
}

            
init() public method

初始化物件。

在物件使用給定的組態初始化之後,會在建構子的結尾調用此方法。

public void init ( )

                public function init()
{
    if ($this->request === null) {
        $this->request = Yii::$app->getRequest();
    }
    if ($this->response === null) {
        $this->response = Yii::$app->getResponse();
    }
}

            
isActive() protected method

定義於: yii\base\ActionFilter::isActive()

傳回值,指示篩選器是否對給定的動作處於活動狀態。

protected boolean isActive ( $action )
$action yii\base\Action

正在被過濾的 action

return boolean

判斷給定的 action 此過濾器是否為啟用狀態。

                protected function isActive($action)
{
    $id = $this->getActionId($action);
    if (empty($this->only)) {
        $onlyMatch = true;
    } else {
        $onlyMatch = false;
        foreach ($this->only as $pattern) {
            if (StringHelper::matchWildcard($pattern, $id)) {
                $onlyMatch = true;
                break;
            }
        }
    }
    $exceptMatch = false;
    foreach ($this->except as $pattern) {
        if (StringHelper::matchWildcard($pattern, $id)) {
            $exceptMatch = true;
            break;
        }
    }
    return !$exceptMatch && $onlyMatch;
}