我有2个PHP文件。一个文件是caller.php,另一个是worker.php
caller.php将在(linux)系统上启动worker.php并且caller.php应该立即结束(而worker.php仍然在服务器上运行)
worker.php占用了大量时间,它会将状态写入数据库或文件。
我希望能够在启动'php worker.php'的浏览器中打开caller.php,关闭浏览器,在5分钟后返回并检查状态..(或者脚本将在完成后发送邮件) - 任何想法如何做到这一点?
答案 0 :(得分:2)
您可以结束客户端连接并继续处理,全部完成。如果处理比php / httpd全局配置允许的时间更长,您可能还想增加php超时。请参阅set_time_limit();
。
这不是你提出的问题,但我认为这可能是X / Y问题所以我们在这里使用的技术可以用来:
所以基本上这可以回答你描述的需求,而不是“如何做X?”。
// Ignore user abort and set Connection close header
ignore_user_abort(true);
header("Connection: close");
// Start controlled buffering
ob_start();
echo "<h1>Processing started, come back tomorrow to see results</h1>";
// Get buffer length and manually add it to headers.
$size = ob_get_length();
header("Content-Length: $size");
// Flush buffers, user sees "Processing started" message.
ob_end_flush();
flush();
// At this point connection to client should be closed already.
// Here we start our worker, there is no need to do fork() or
// anything like that. Client browser is not listening anymore.
// All we need to do is simply start working and start writing
// status logs to somewhere so that client can retrieve status
// with another request, let's say from checkworkerstatus.php
include "worker.php";
$worker = new worker();
$worker->start_long_processing();
caller
让worker
单独运行?这是对的,那是因为没有必要。
是的,你问过“caller.php会在(linux)系统上启动worker.php的行为,而caller.php应该立即结束(而worker.php仍在服务器上运行)”< / i>的。但是,如果您不想multithreading-singleuser app with php,则无需这样做。只需让用户 1。启动一些东西, 2。让它继续运行, 3。断开用户连接, 4。 go回到开始,用户可以开始更多的东西,或者如果已经足够无聊就退出。
当然你可以用flush();
之后的任何内容替换所有内容,不同之处在于客户端不再监听,以便所有输出都转到名为/ dev / null的黑洞。例如,用这样的东西测试它:
...end_flush();
flush();
// At this point connection to client should be closed already.
echo "Nobody sees this message";
while(rand(0,10) != 1) {
echo "Nobody sees this message";
error_log(date("mdyHis")." Still running...");
sleep(10);
}
...
有关详细信息,请参阅http://php.net/features.connection-handling 如果刷新缓冲区和关闭用户连接似乎有任何问题,也请阅读http://php.net/function.flush 关于Why does PHP not support multithreading?
还有另一个问题(有答案)答案 1 :(得分:1)
如果您将配置Apache / nginx,它将允许同时执行两个PHP文件(就像我的一样)。
您应该阅读posix_mkfifo:http://php.net/manual/en/function.posix-mkfifo.php(也有使用示例)。
答案 2 :(得分:1)
这可能有点强,但是最快捷直接的方式:
代码:
ignore_user_abort(true);
set_time_limit(0);
当你关闭浏览器工作者(应该)计数工作时!
请参阅http://www.php.net/manual/en/function.ignore-user-abort.php