2012-04-14 47 views
2

我想防止我的脚本被淹没 - 如果用户点击F5,它将每次都执行脚本。防止PHP脚本被淹没

我想防止这种情况,并允许每2秒执行一次脚本,有没有解决方案?

+0

我知道你选择了我的答案,但...感觉就像为你写了一个改进版本......查看更新脚本的答案 – Baba 2012-04-14 17:42:41

+0

@Baba非常感谢你! :) – Lucas 2012-04-15 14:14:23

回答

14

您可以使用内存缓存来做到这一点..

简单演示脚本

$memcache = new Memcache(); 
$memcache->connect ('localhost', 11211); 
$runtime = $memcache->get ('floodControl'); 

if ((time() - $runtime) < 2) { 
    die ("Die! Die! Die!"); 
} 

else { 
    echo "Welcome"; 
    $memcache->set ("floodControl", time()); 
} 

这仅仅是一个示例代码..也有考虑,如

A.另一件事Better IP地址检测(Proxy,Tor)

B. Current Action

每分钟等

C.最长执行...

D.班用户最大洪水等

EDIT 1 - 改进版

用法

$flood = new FloodDetection(); 
$flood->check(); 

echo "Welcome" ; 

class FloodDetection { 
    const HOST = "localhost"; 
    const PORT = 11211; 
    private $memcache; 
    private $ipAddress; 

    private $timeLimitUser = array (
      "DEFAULT" => 2, 
      "CHAT" => 3, 
      "LOGIN" => 4 
    ); 
    private $timeLimitProcess = array (
      "DEFAULT" => 0.1, 
      "CHAT" => 1.5, 
      "LOGIN" => 0.1 
    ); 

    function __construct() { 
     $this->memcache = new Memcache(); 
     $this->memcache->connect (self::HOST, self::PORT); 
    } 

    function addUserlimit($key, $time) { 
     $this->timeLimitUser [$key] = $time; 
    } 

    function addProcesslimit($key, $time) { 
     $this->timeLimitProcess [$key] = $time; 
    } 

    public function quickIP() { 
     return (empty ($_SERVER ['HTTP_CLIENT_IP']) ? (empty ($_SERVER ['HTTP_X_FORWARDED_FOR']) ? $_SERVER ['REMOTE_ADDR'] : $_SERVER ['HTTP_X_FORWARDED_FOR']) : $_SERVER ['HTTP_CLIENT_IP']); 
    } 

    public function check($action = "DEFAULT") { 
     $ip = $this->quickIP(); 
     $ipKey = "flood" . $action . sha1 ($ip); 

     $runtime = $this->memcache->get ('floodControl'); 
     $iptime = $this->memcache->get ($ipKey); 

     $limitUser = isset ($this->timeLimitUser [$action]) ? $this->timeLimitUser [$action] : $this->timeLimitUser ['DEFAULT']; 
     $limitProcess = isset ($this->timeLimitProcess [$action]) ? $this->timeLimitProcess [$action] : $this->timeLimitProcess ['DEFAULT']; 

     if ((microtime (true) - $iptime) < $limitUser) { 
      print ("Die! Die! Die! $ip") ; 
      exit(); 
     } 

     // Limit All request 
     if ((microtime (true) - $runtime) < $limitProcess) { 
      print ("All of you Die! Die! Die! $ip") ; 
      exit(); 
     } 

     $this->memcache->set ("floodControl", microtime (true)); 
     $this->memcache->set ($ipKey, microtime (true)); 
    } 

} 
+1

我正在考虑upvote。直到你使用Singleton的那一刻。 – 2012-04-14 18:37:07

+0

haaaa ..我会马上改变它.. +1感谢您的观察 – Baba 2012-04-14 18:43:16

+0

完成... @truth ..希望你现在可以重新考虑... – Baba 2012-04-14 18:45:49

4
  1. 将脚本的上次执行时间存储在数据库或 文件中。
  2. 从该文件/数据库读取并与当前时间进行比较。
  3. 如果差值小于2秒,请终止脚本。
  4. 否则,正常继续。
+0

Shoudnt我使用这个会话吗? – Lucas 2012-04-14 16:40:41

+2

如果用户没有保留cookie,则会话无效,脚本不会调节。 – 2012-04-14 16:41:14

2

您可以使用cookies(可以禁用),所以不是一个好主意,或者您可以使用将他的IP地址存储在数据库中,所以如果更多,则X尝试使用相同的IP地址,执行代码,只是如果else语句,你将需要请求IP地址的时间的表,如果你不想使用数据库,那么你可以使用下面的代码

$file = "file.txt"; 
$file_content = file_get_contents($file); 
$fh = fopen($file, 'w') or die("could not open file"); 
$now = time(); 
if($now - $file_content > 60){ 
// your code here 
fwrite($fh, $now); 
}else{ 
echo "Try again later"; 
} 
fclose($fh); 
尝试

但在这种情况下,它不会是每个访问者,而是所有的访问者(所以说用户A来了并执行脚本,用户B将不能执行它,直到60秒过去。

0

最好的方法是将时间存储在服务器端。如果您将信息留在客户端,那么很容易通过。

我会例如将时间戳保存在表中。输入并检查垃圾邮件您的脚本。而容易设定宽容。

0

使用ap ap c缓存或mencache存储信息存储到数据库或从文件中读取我认为是时间/资源消耗