AntiSpam.php 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. <?php
  2. namespace PhpLife\Frame\Library;
  3. /**
  4. * IP频率限制,一定程度上反垃圾
  5. */
  6. class AntiSpam
  7. {
  8. const ANTI_SPAM_MINUTE = 'anti_spam:minute';
  9. const ANTI_SPAM_HOUR = 'anti_spam:hour';
  10. const ANTI_SPAM_DAY = 'anti_spam:year';
  11. const ANTI_SPAM_LOCKED = 'anti_spam:locked';
  12. // 频率设置
  13. protected static $limits = array(
  14. self::ANTI_SPAM_MINUTE => 500,
  15. self::ANTI_SPAM_HOUR => 2000,
  16. self::ANTI_SPAM_DAY => 10000,
  17. );
  18. // 正常过期
  19. protected static $expire = array(
  20. self::ANTI_SPAM_MINUTE => 60,
  21. self::ANTI_SPAM_HOUR => 3600,
  22. self::ANTI_SPAM_DAY => 86400,
  23. );
  24. // 封禁时间
  25. protected static $forbiddenTime = array(
  26. self::ANTI_SPAM_MINUTE => 60,
  27. self::ANTI_SPAM_HOUR => 3600,
  28. self::ANTI_SPAM_DAY => 86400,
  29. );
  30. public static function check()
  31. {
  32. // 检查是否已经被封杀
  33. if (self::getConnection()->get(self::getKey(self::ANTI_SPAM_LOCKED))) {
  34. return FALSE;
  35. }
  36. foreach (self::$limits as $key => $limit) {
  37. $expire = self::$expire[$key];
  38. $key = self::getKey($key);
  39. $value = self::getConnection()->get($key);
  40. if (!$value) {
  41. // 值不存在就设置
  42. self::getConnection()->set($key, 1, $expire);
  43. } elseif ($value > $limit) {
  44. // 封禁时间
  45. $expire = self::$forbiddenTime[$key];
  46. self::getConnection()->set(self::getKey(self::ANTI_SPAM_LOCKED), 1, $expire);
  47. return FALSE;
  48. } else {
  49. // 正常情况下+1
  50. self::getConnection()->increment($key, 1);
  51. }
  52. }
  53. return TRUE;
  54. }
  55. protected static function getKey($key)
  56. {
  57. $ip = \PhpLife\Frame\Helper::getClientIp(TRUE);
  58. return $key . ':' . $ip;
  59. }
  60. protected static function getConnection()
  61. {
  62. static $connection = null;
  63. if ($connection) {
  64. return $connection;
  65. }
  66. $cfg = \PhpLife\Config\Memcache\AntiSpam::getData();
  67. $connection = new \Memcached;
  68. $connection->setOption(\Memcached::OPT_COMPRESSION, TRUE);
  69. $connection->setOption(\Memcached::OPT_DISTRIBUTION, TRUE);
  70. $connection->setOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE, TRUE);
  71. $connection->setOption(\Memcached::OPT_NO_BLOCK, TRUE);
  72. $connection->setOption(\Memcached::OPT_CONNECT_TIMEOUT, 50);
  73. $connection->setOption(\Memcached::OPT_POLL_TIMEOUT, 50);
  74. $connection->addServers($cfg);
  75. return $connection;
  76. }
  77. }