代码之家  ›  专栏  ›  技术社区  ›  Rod

如何在PHP中刷新数据并断开用户连接但保持脚本活动

  •  5
  • Rod  · 技术社区  · 16 年前

    这是一个技巧性的问题,在开发一个php+ajax应用程序时,我感觉到了一些长的查询,它们没有什么问题,但是它们可以在后台完成。

    我知道有一种方法可以在exec()将实际处理扔给另一个进程的同时只向用户发送一个回复,但是它对我来说并不合适,这可能会产生漏洞,而且在使它与虚拟服务器和跨平台兼容方面也不实际。

    PHP提供了ob_*函数,尽管它们有助于刷新缓存,但是用户将保持连接,直到脚本运行。

    我想知道,在向用户发送数据并用Apache关闭连接/线程之后,是否有一个exec替代方法来保持脚本的运行,或者用一种不太“脏”的方法将处理数据发送到另一个脚本。

    4 回复  |  直到 16 年前
        1
  •  2
  •   Mitch Dempsey    16 年前

    我在网站上使用的是 Gearman .

    Gearman允许您通过命令行在后台运行任务工作者。这些工作人员监听特定任务的请求,然后在收到请求时对其进行处理。

    在Web应用程序方面,我只是 $GEARMAN->doBackground("task_name","task_data"); 然后任务被发送给工作人员,执行立即返回到脚本。

    这比做要安全得多 exec 因为gearman任务作为php函数运行。

        2
  •  1
  •   Rod    16 年前

    在做了一些研究之后,我找到了这个问题的3个答案:

    1. 以较低的超时值执行Ajax请求,一旦达到超时值,JS将继续执行下一步,而PHP将在后台 ignore_user_abort 已启用,将继续处理。

    2. 将慢进程与直接响应用户进行即时回复或部分回复(如果可能,视情况而定)的脚本分开,将慢进程变量存储到会话或数据库中,通过低超时值的curl将其发送给工作进程,或者让cron任务调用工作进程。

    3. 使用Grdman。

        3
  •  0
  •   ceejayoz    16 年前

    PHP有一个名为 ignore_user_abort 为此。

    您还可以在数据库中存储一个要执行的任务队列,并 cron 任务定期检查新任务,并在新任务到达时进行处理。

        4
  •  0
  •   Geek Num 88 Walter    16 年前

    我有一个PHP类,它是一个POSIX守护进程。我开始了,基本上剧本

    while(1)
    {
     // run task
    }
    

    您可以将数据库调用和所有内容放入循环中—它也响应POSIX信号—我通常将其设置为休眠120秒,然后再次运行。我把它和我排队的小桌子一起用。所以不用致命的 exec() 我可以使用一个更安全的准备好的语句将ID插入到我的队列表中,后台脚本将在接下来的30秒内捕获该ID。

    警告-我确实会杀死守护进程,每3小时重新启动一次,因为有时它会被卡住,不再进行任何处理-但是,每3小时一次简单的杀戮和启动对于让实时队列运行是一个很好的折衷。

    编辑 我不想发布整个脚本,但如果有人想要,我可以