在PHP中维护浏览器选项卡之间的状态

时间:2010-07-28 19:48:49

标签: php session

我正在构建一个允许用户针对两个数据库之一运行查询的Web应用程序。它们只允许一次向每个数据库提交1个查询。目前,我正在设置$ _SESSION ['runningAdvancedQuery'](例如),让我知道他们是否正在运行查询。这是为了防止有人打开第二个浏览器选项卡并再次点击该资源。除了......之外它很棒。

如果我在选项卡中启动查询,然后在完成之前关闭该选项卡,则不会取消设置该标志。因此,如果我重新打开页面,我无法运行任何查询,因为它认为我还有一个正在运行。任何人都有建议绕过这个?

3 个答案:

答案 0 :(得分:1)

将此值设置为不是例如1,而是设置为unix时间戳,并通过comprasion last-query-timestamp检查到现在,设置执行下一个查询必须经过的时间差。记住将块时间设置为安全值 - 可以执行查询的最长时间。如果用户关闭他的标签,在短时间后他将被“解锁”。

答案 1 :(得分:1)

<?php
ignore_user_abort(true);

//if session variable is not set
    //set session variable
    //run query
    //unset session variable
//else
    //show error: "your other query isn't finished yet"

?> 

答案 2 :(得分:1)

不是将$_SESSION['runningAdvancedQuery'];设置为true,而是将其设置为SELECT CONNECTION_ID();的输出,并检查show processlist;是否仍在运行。这将是其他答案的补充:特别是当使用持久连接时,其他进程可能会使用connection_id。

作为同一个用户,您始终可以看到自己的流程。所以,结合其他检查:

  1. 存储时间戳,connection_id&amp;实际的sql-query(我将删除所有空格和&amp;强制转换为上部或下部字符串,以避免演示文稿与内容略有不同)。
  2. 当然使用ignore_user_abort()功能,在查询之前执行session_write_close(),重启会话&amp;在查询后将其设置为完成。
  3. 检查正在运行的查询,检查是否
    • 连接ID仍然存在。
    • 查询运行的时间戳+秒合理地接近当前时间。
    • 查询(小写,剥离的空格)与请求的查询大致相同(使用SHOW FULL PROCESSLIST;来获取整个查询。)
  4. 可选地,更进一步,让人们有KILL QUERY <connection_id>;的可能性(只有前3次检查都是正面的)。