2014-01-16 82 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