加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

如何在不阻塞线程的情况下调用PHP?

发布时间:2020-12-13 17:12:29 所属栏目:PHP教程 来源:网络整理
导读:我有2个 PHP文件.一个文件是caller.php,另一个是worker.php caller.php将在(linux)系统上启动worker.php并且caller.php应该立即结束(而worker.php仍然在服务器上工作) worker.php占用了大量时间,它会将状态写入数据库或文件. 我希望能够在浏览器中打开caller
我有2个 PHP文件.一个文件是caller.php,另一个是worker.php

caller.php将在(linux)系统上启动worker.php并且caller.php应该立即结束(而worker.php仍然在服务器上工作)

worker.php占用了大量时间,它会将状态写入数据库或文件.

我希望能够在浏览器中打开caller.php,启动’php worker.php’,关闭浏览器,在5分钟后返回并检查状态..(或者脚本将在完成后发送邮件) – 任何想法怎么做?

解决方法

您可以结束客户端连接并继续处理,全部完成.如果处理比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.php将在(linux)系统上启动worker.php并且caller.php应该立即结束(而worker.php仍然在服务器上运行)”的行为.但是,如果您不想这样做,就没有必要这样做.只需让用户1.开始运行,2.让它运行,3.断开用户,4.回到用户可以开始的地方更多的东西或者已经足够无聊就退出.

当然你可以在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?还有另一个问题(答案)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读