2014-01-16 119 views
1

我一直在尋找一種方法來防止同時運行php腳本。所以我找到了一種方法(在這個網站上)來防止這種情況發生。這是我帶來的地方(測試文件)。防止php腳本同時運行和兩次

鏈接找到解決辦法的計算器:How to prevent PHP script running more than once?

test.php的

echo "started: ".microtime()."<br>"; 

$lock = $_SERVER['DOCUMENT_ROOT'].'/tmp/test.lock'; 
$f = fopen($lock, 'x'); 
if($f === false){ 
    die("\nCan't aquire lock\n"); 
}else{ 
    // Do processing 
    echo "Working: ".microtime()."<br>"; 
    sleep(5); 

    echo "Still working: ".microtime()."<br>"; 
    sleep(5); 

    echo "Ready: ".microtime()."<br>"; 
    fclose($f); 
    unlink($lock);  
} 

運行此腳本的第一次,輸出將是這樣的:

started: 0.87157000 1389879936 
Working: 0.0 1389879936 
Still working: 0.87542000 1389879941 
Ready: 0.87551800 1389879946 

現在當我在同一個瀏覽器中同時運行同一個腳本時,兩者都會被執行,但是第二個腳本會在第一個腳本之後執行。所以不是同時,而是兩次。我沒有想到,因爲如果test.lock文件已經存在,它應該會死掉。

所以運行在兩個標籤相同的瀏覽器的腳本,這是結果:

TAB1:

started: 0.87157000 1389879936 
Working: 0.0 1389879936 
Still working: 0.87542000 1389879941 
Ready: 0.87551800 1389879946 

TAB2:

started: 0.92684500 1389879946 
Working: 0.92911700 1389879946 
Still working: 0.92920300 1389879951 
Ready: 0.92930400 1389879956 

正如你所看到的,腳本在2e選項卡中,當第一個選項卡中的腳本完成時啓動。這不是we?嗎?

當我在不同的瀏覽器上執行此操作時,由於第二個腳本被終止,所以它起作用。

瀏覽器1:

started: 0.62890800 1389880056 
Working: 0.63861900 1389880056 
Still working: 0.63878800 1389880061 
Ready: 0.63893300 1389880066 

瀏覽器2:

started: 0.10137700 1389880058 

Warning: fopen(/home/users/domain/tmp/test.lock) [function.fopen]: failed to open stream: File exists in /home/users/domain/test.php on line 8 
Can't aquire lock 

問題

我現在可以防止執行腳本的同時,但如何防止第二腳本在第一個腳本完成後被執行的同一個瀏覽器中!

+0

好吧,例如只是創建一個永久文件,而不是一個鎖文件。 – Lexib0y

+0

@ Lexib0y:如果需要,它必須能夠第二次運行腳本。但是,如果瀏覽器已經運行,則必須停止瀏覽器。現在瀏覽器一直等到另一個標籤準備就緒。我必須停下來,不要等待! – Timo002

+0

如果您在else語句的開頭關閉鎖定文件會怎麼樣? – NotABlueWhale

回答

1

我猜在同一個瀏覽器中的兩個選項卡計數爲相同的客戶端,瀏覽器將使用相同的會話。服務器將依次回答來自同一會話的請求。這就是爲什麼您可以使用多個選項卡登錄到相同的服務。 (例如,在計算器中打開多個選項卡)

可以同時處理來自不同會話(瀏覽器)的請求。我想這取決於你的服務器。

你不能真正阻止腳本被一個簡單的鎖定文件執行兩次。正如您已經證明的那樣,您只能阻止同時執行。

如果您想防止同一個客戶端經常執行腳本,您需要跟蹤他們上次執行腳本的時間。 (可能在一個cookie /數據庫)

+0

我同意你的理論,看起來這是我必須忍受的。當腳本準備就緒時,可能會在數據庫中設置時間戳,並且在完成後的1分鐘內不讓它再次運行。 – Timo002

+1

好吧,你可以做一些事情,比如不要刪除你的鎖文件,除非你創建文件時使用了filemtime或者stat。即。不要在腳本結尾刪除鎖定文件。在腳本開始處(如果now()) - 時間戳< limit ->退出,否則用當前時間觸摸你的lockfile並運行 – Loopo

+0

我知道這是一箇舊帖子。我發現在兩個選項卡中唯一不同的是'$ GLOBALS ['REQUEST_TIME']'變量。這是腳本啓動的時間戳。我不知道這是否有用,但它確實允許腳本區分兩個啓動實例。 – Branndon