我有两个用户可以调用的脚本(A 和 B)。
如果用户调用 A,我会做一堆数据库访问并检索结果返回给用户。在我弄清楚我需要发回的内容之后,我会对数据库进行大量额外的处理和修改。
我想知道是否可以将结果返回给用户,然后在某种后台任务中执行其余的处理。
更进一步的条件是,如果调用脚本A的用户随后调用脚本B,则用户调用A触发的任何处理任务必须完成,或者脚本B必须等待直到它完成。
有没有办法做到这一点?
我有两个用户可以调用的脚本(A 和 B)。
如果用户调用 A,我会做一堆数据库访问并检索结果返回给用户。在我弄清楚我需要发回的内容之后,我会对数据库进行大量额外的处理和修改。
我想知道是否可以将结果返回给用户,然后在某种后台任务中执行其余的处理。
更进一步的条件是,如果调用脚本A的用户随后调用脚本B,则用户调用A触发的任何处理任务必须完成,或者脚本B必须等待直到它完成。
有没有办法做到这一点?
关闭请求后,php 无法执行任务,因为请求(以及发送到浏览器的响应)在 php 进程完成时真正关闭。
此外,php 适合短期操作,而不是像守护进程这样长时间运行的程序,因为 php 缺乏良好的垃圾收集器(因此它会在崩溃之前耗尽所有可用内存)。
您要查找的内容称为队列。当您需要执行一些资源(或时间)密集型任务时,您将任务放入队列中。然后稍后一个工作进程将从队列中取出一个项目然后执行任务。
这使您能够通过限制工作人员的数量来限制资源使用,以避免出现高峰和服务故障。
查看 resque(对于自托管解决方案)或 iron.io(对于云,设置免费解决方案)
如果您在共享主机上(因此,没有可用的队列和 cron),那么我建议您查看 iron.io 推送队列。当队列不为空时,这种队列将调用您的服务器(通过 HTTP)向其发送任务。这样,所有轮询/检查队列都在 iron.io 端完成,您只需设置一个常规页面即可执行您的任务。
此外,如果您希望脚本 B 等待脚本 A 完成,则必须创建某种锁定系统。但如果我是你,我会尽量避免这种情况,因为这会导致死锁(一个线程等待另一个线程,但另一个线程永远不会完成,从而永远阻塞等待的线程)
你可以这样做:
一个.php
<?php
echo "hi there!";
//in order to run another program in background you have to
//redirect std e err output and use &
//otherwise php will wait for the output
$cmd = "/usr/bin/php ".__DIR__."/b.php";
`$cmd > /dev/null 2> /dev/null &`;
echo "<br>";
echo "finished!";
b.php
<?php
$f = fopen(__DIR__."/c.txt", "w");
//some long running task
for($i=0; $i<300; $i++){
fwrite($f, "$i\n");
sleep(1);
}
fclose($f);
笔记:
我猜你正在寻找Ignore_user_abort()
. 当浏览器关闭连接时,此功能使您的脚本保持活动状态以进行清理任务。
http://php.net/manual/en/function.ignore-user-abort.php
header()
您可以通过, set_time_limit()
, ignore_user_abort()
,的良好组合虚拟地分叉浏览器请求connection_status()
。
与 Ajax 结合起来非常有趣。
做这样的事情最好使用nodejs
,PHP 是同步的,并逐行完成它的工作。(你也可以在lib之类python
的其他东西中开发异步代码)。asyncore
但是对于您的问题,您应该开发如下内容:
set_time_limit(0);
ignore_user_abort();
// Working With database
// Echo data to user
ob_end_flush();
ob_flush();
flush();
// Second part of database access,this can be take longer
看看ob_flush() php 函数,它不会等待结束进程,然后为用户呈现 html。