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() 检查属性是否设置,即定义且不为空。 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

受保护方法

隐藏继承方法

方法 描述 定义位置
getActionId() 通过将 yii\base\Action::$uniqueId 转换为相对于模块的 ID 来返回操作 ID。 yii\base\ActionFilter
isActive() 返回一个值,指示过滤器对于给定操作是否处于活动状态。 yii\base\ActionFilter

属性详情

隐藏继承属性

$enableRateLimitHeaders 公共属性

是否在响应中包含速率限制头

$errorMessage 公共属性

速率限制超过时显示的消息

public string $errorMessage '速率限制超过。'
$request 公共属性

当前请求。如果未设置,将使用 request 应用程序组件。

$response 公共属性

要发送的响应。如果未设置,将使用 response 应用程序组件。

$user 公共属性

实现 RateLimitInterface 的用户对象。如果未设置,它将采用 Yii::$app->user->getIdentity(false) 的值。 {@since 2.0.38} 可以提供闭包函数以便在运行时分配用户标识。当您 **不** 使用标准 Yii::$app->user 组件时,建议使用闭包分配用户标识。请参见下面的示例: `php 'user' => function() {

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

} `

方法详情

隐藏继承方法

__call() 公共方法

定义在: yii\base\BaseObject::__call()

调用不是类方法的命名方法。

不要直接调用此方法,因为它是一个 PHP 魔术方法,将在调用未知方法时隐式调用。

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

方法名称

$params array

方法参数

返回 mixed

方法返回值

抛出 yii\base\UnknownMethodException

当调用未知方法时

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

            
__construct() 公共方法

定义在: 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() 公共方法

定义在: yii\base\BaseObject::__get()

返回对象属性的值。

不要直接调用此方法,因为它是一个 PHP 魔术方法,将在执行 $value = $object->property; 时隐式调用。

另请参阅 __set()

public mixed __get ( $name )
$name string

属性名称

返回 mixed

属性值

抛出 yii\base\UnknownPropertyException

如果属性未定义

抛出 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() 公共方法

定义在: yii\base\BaseObject::__isset()

检查属性是否设置,即定义且不为空。

不要直接调用此方法,因为它是一个 PHP 魔术方法,将在执行 isset($object->property) 时隐式调用。

请注意,如果属性未定义,将返回 false。

另请参阅 https://php.ac.cn/manual/en/function.isset.php

public boolean __isset ( $name )
$name string

属性名称或事件名称

返回 boolean

命名的属性是否已设置(不为空)。

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

            
__set() 公共方法

定义在: yii\base\BaseObject::__set()

设置对象属性的值。

不要直接调用此方法,因为它是一个 PHP 魔术方法,将在执行 $object->property = $value; 时隐式调用。

另请参阅 __get()

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

属性名称或事件名称

$value mixed

属性值

抛出 yii\base\UnknownPropertyException

如果属性未定义

抛出 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() 公共方法

定义在: yii\base\BaseObject::__unset()

将对象属性设置为 null。

不要直接调用此方法,因为它是一个 PHP 魔术方法,将在执行 unset($object->property) 时隐式调用。

请注意,如果属性未定义,此方法将不做任何事。如果属性是只读属性,它将抛出异常。

另请参阅 https://php.ac.cn/manual/en/function.unset.php

public void __unset ( $name )
$name string

属性名称

抛出 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 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() 公共方法

定义在: yii\base\ActionFilter::afterAction()

此方法在执行操作后立即调用。

您可以重写此方法以对操作进行一些后期处理。

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

刚刚执行的操作。

$result mixed

操作执行结果

返回 mixed

已处理的操作结果。

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

            
afterFilter() 公共方法
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() 公共方法

定义于: 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

要执行的操作。

返回 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

定义于: yii\base\BaseObject::canGetProperty()

返回一个值,指示是否可以读取属性。

属性是可读的,如果

  • 该类具有与指定名称关联的 getter 方法(在这种情况下,属性名称不区分大小写);
  • 该类具有与指定名称相同的成员变量(当 $checkVars 为 true 时);

另见 canSetProperty()

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

属性名称

$checkVars boolean

是否将成员变量视为属性

返回 boolean

属性是否可读

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

            
canSetProperty() public method

定义于: yii\base\BaseObject::canSetProperty()

返回一个值,指示是否可以设置属性。

属性是可写的,如果

  • 该类具有与指定名称关联的 setter 方法(在这种情况下,属性名称不区分大小写);
  • 该类具有与指定名称相同的成员变量(当 $checkVars 为 true 时);

另见 canGetProperty()

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

属性名称

$checkVars boolean

是否将成员变量视为属性

返回 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

要执行的操作

抛出 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 代替。

定义于: yii\base\BaseObject::className()

返回此类的完全限定名。

public static string className ( )
返回 string

此类的完全限定名称。

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

            
detach() public method

定义于: 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

定义于: yii\base\Behavior::events()

$owner 的事件声明事件处理程序。

子类可以覆盖此方法以声明应将哪些 PHP 回调附加到 $owner 组件的事件。

当行为附加到所有者时,回调将附加到 $owner 的事件;当行为从组件分离时,它们将从事件分离。

回调可以是以下任何一项

  • 此行为中的方法:'handleClick',等效于 [$this, 'handleClick']
  • 对象方法:[$object, 'handleClick']
  • 静态方法:['Page', 'handleClick']
  • 匿名函数:function ($event) { ... }

以下是一个例子

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

事件(数组键)和相应的事件处理程序方法(数组值)。

                public function events()
{
    return [];
}

            
getActionId() protected method (available since version 2.0.7)

定义于: yii\base\ActionFilter::getActionId()

通过将 yii\base\Action::$uniqueId 转换为相对于模块的 ID 来返回操作 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

定义于: yii\base\BaseObject::hasMethod()

返回一个值,指示是否定义了方法。

默认实现是调用 php 函数 method_exists()。当您实现 php 魔术方法 __call() 时,您可能会覆盖此方法。

public boolean hasMethod ( $name )
$name string

方法名称

返回 boolean

方法是否已定义

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

            
hasProperty() public method

定义于: yii\base\BaseObject::hasProperty()

返回一个值,指示是否定义了属性。

属性已定义,如果

  • 该类具有与指定名称关联的 getter 或 setter 方法(在这种情况下,属性名称不区分大小写);
  • 该类具有与指定名称相同的成员变量(当 $checkVars 为 true 时);

另见

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

属性名称

$checkVars boolean

是否将成员变量视为属性

返回 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() 受保护的方法

定义于: yii\base\ActionFilter::isActive()

返回一个值,指示过滤器对于给定操作是否处于活动状态。

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

正在过滤的动作

返回 boolean

过滤器对于给定动作是否处于活动状态。

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