5

我正在用 PHP 开发一个 WebApp。用户将能够单击一个按钮,PHP 代码最终将调用系统执行程序。由于 WebApp 将使用 AJAX,因此用户可能会单击该按钮两次,或者确实单击另一个按钮会启动另一个执行进程。

现在,我知道我可以编写一些 javascript 来禁用按钮,直到单个事件完成。但是,这是客户端强制执行,很容易被覆盖。

我可以在 PHP 方面做些什么来阻止这样的事情发生吗?在我的脑海中,我有一个想法,让会话变量充当“信号量”,在执行每个脚本之前,将检查这个变量,并且必须在脚本继续之前返回 0。

我这样做对吗?或者这是否只是为死锁/竞争条件打开了一罐蠕虫?

谢谢

更新:只是把它放在上下文中,我正在开发的系统将用于启动、停止和重新映像虚拟专用服务器。如果按下重新映像按钮,PHP 脚本将调用一些 bash 脚本来开始重新映像 VPS。但是,如果用户在此过程中尝试启动 VPS....

4

3 回答 3

1

您可以使用jQuery.ajax()并将选项设置async为 false:

async默认值:true 默认情况下,所有请求都是异步发送的(即默认设置为 true)。如果您需要同步请求,请将此选项设置为 false。跨域请求和 dataType: "jsonp" 请求不支持同步操作。请注意,同步请求可能会暂时锁定浏览器,从而在请求处于活动状态时禁用任何操作

你可以像这样使用它:

$.ajax({
    type: "POST",
    url: "file.php",
    async: false,
    data: data,
    success: function(return){
        alert("Success: "+return);
    }
});

如果要添加加载器,只需将其应用为:

startLoader();
$.ajax({
    type: "POST",
    url: "file.php",
    async: false,
    data: data,
    success: function(return){
        alert("Success: "+return);
    }
});
endLoader();

但是,您的 PHP 想法根本不是一个好的想法。打开会话并为此类事情执行所有过程只是无用的,并且会减慢您的脚本速度。你应该问自己:我真的需要阻止这个吗?

如果答案是肯定的,那么请执行以下操作:processes在您的数据库中创建一个名为的表。在该表中创建 2 个字段:一个将是进程标识符:process_id;第二个是进程状态:process_status。第一个是您将使用 sha1(IMAGE) 定义的整数。第二个将是一个整数:1表示“忙”,0表示“空闲”。

然后你可以做这样的事情:

SELECT process_status FROM vps_processes WHERE process_id = sha1(CURRENT_IMAGE);

并检查它是什么10. 如果是1则阻止脚本;如果是,0那么您查询:

UPDATE vps_processes SET process_status = 1 WHERE process_id = sha1(CURRENT_IMAGE);

然后运行您必须运行的内容并在脚本查询结束时运行:

UPDATE vps_processes SET process_status = 0 WHERE process_id = sha1(CURRENT_IMAGE);
于 2011-04-22T13:15:34.317 回答
0

您希望它成为服务器端解决方案的事实使我怀疑您不信任这里的用户。那么您显然不能使用会话结构,因为客户端也可以绕过它。相反,您必须锁定单个 IP 地址或一些类似的方法。也许有一个包含锁定文件的文件夹,您可以在其中创建一个以执行请求的 IP 命名的文件。

于 2011-04-22T13:19:01.027 回答
0

除非您想在不同机器之间强制执行每个用户的限制,否则您始终可以使用http://php.net/manual/en/function.flock.php将操作锁定在名为lock.$username

或者,您可能根本不关心强制执行限制,因为无论如何只有有限数量的 php 进程将同时运行。

于 2011-04-22T13:19:29.467 回答