我正在用PHP开发WebApp。用户可以单击一个按钮,PHP代码最终将调用系统执行程序。由于WebApp将使用AJAX,因此用户可能会单击该按钮两次,或者确实单击另一个将启动另一个exec进程的按钮。
现在,我知道我可以编写一个小的javascript来禁用按钮,直到单个事件完成。但是,这是客户端强制执行,很容易被覆盖。
我是否可以在PHP方面做些事来阻止这样的事情发生?在我看来,我有一个会话变量充当“信号量”的想法,并且在每个脚本执行之前,将检查此变量,并且必须在脚本继续之前返回0。
我是否正确的方式?或者这只会为死锁/竞争条件打开一堆蠕虫?
由于
更新: 只是将其置于上下文中,我正在开发的系统将用于启动,停止和重新映像虚拟专用服务器。如果按下了重新映像按钮,PHP脚本将调用一些bash脚本开始重新映像VPS。但是,如果用户在完成此操作时尝试启动VPS ....
答案 0 :(得分:1)
您可以使用jQuery.ajax()
并将选项async
设置为false:
async 默认值:true默认情况下,所有请求都是异步发送的 (即默认设置为true)。 如果需要同步请求,请设置 这个选项为false。跨域 requests和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);
并检查它是1
还是0
。如果是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);
答案 1 :(得分:0)
您希望它成为服务器端解决方案的事实让我怀疑您不信任此处的用户。然后你显然不能使用会话结构,因为这也可以由客户端规避。相反,您必须锁定单个IP地址或类似的方法。也许有一个包含锁定文件的文件夹,您可以在其中创建一个以执行请求的IP命名的文件。
答案 2 :(得分:0)
除非您要强制执行不同计算机之间的每用户限制,否则您始终可以使用http://php.net/manual/en/function.flock.php锁定名为lock.$username
或者,您可能根本不关心强制执行限制,因为只有有限数量的php进程将在同一时间运行。