2012-04-14 99 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存儲信息存儲到數據庫或從文件中讀取我認爲是時間/資源消耗