LimitBehavior.php 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. <?php
  2. namespace common\behaviors;
  3. use Yii;
  4. use yii\base\Behavior;
  5. use yii\web\Controller;
  6. use yii\redis\Connection;
  7. use yii\web\TooManyRequestsHttpException;
  8. use common\helpers\DateHelper;
  9. /**
  10. * 限制点击次数
  11. * 防止重复提交
  12. * Class CounterBehavior
  13. * @package common\behaviors
  14. * @author qimall
  15. */
  16. class LimitBehavior extends Behavior
  17. {
  18. /**
  19. * 请求方法
  20. *
  21. * @var string
  22. */
  23. public $action = "*";
  24. /**
  25. * 用户id
  26. *
  27. * @var int
  28. */
  29. public $userId = 0;
  30. /**
  31. * 过期时间,单位:秒
  32. *
  33. * @var float|int
  34. */
  35. public $second = 2;
  36. /**
  37. * key前缀
  38. * @var string
  39. */
  40. public $prefix = 'REQUESTLIMIT:';
  41. /**
  42. * @return array
  43. */
  44. public function events()
  45. {
  46. return [Controller::EVENT_BEFORE_ACTION => 'beforeAction'];
  47. }
  48. /**
  49. * @param $event
  50. * @throws TooManyRequestsHttpException
  51. */
  52. public function beforeAction($event)
  53. {
  54. // 只有post方式才可以需要此处理
  55. if ($this->userId && Yii::$app->request->isPost) {
  56. /** @var Connection $redis */
  57. $redis = Yii::$app->redis;
  58. // 限流: 用户 + 访问方法
  59. $key = $this->prefix.sprintf('hist_%s_%s', $this->userId, Yii::$app->controller->route);
  60. $res = $redis->set($key,1,'NX','EX',$this->second);
  61. if (!$res) throw new TooManyRequestsHttpException('服务器繁忙,路径:'.Yii::$app->controller->route);
  62. }
  63. }
  64. }