PHP:在等待数据库查询执行时,是否可以将输出滴流到浏览器?

PHP:在等待数据库查询执行时,是否可以将输出滴流到浏览器?,php,multithreading,Php,Multithreading,tl;dr:在等待SQL查询执行时,是否可以定期向浏览器返回一些“虚拟空间”?这意味着在没有返回任何内容时,浏览器不会挂断 长话短说: 我制作了一个针对数据库的小型“web工具”(MS SQL,使用他们的PDO驱动程序) 有时,我运行的查询需要很长时间 大约100秒后,浏览器停止“旋转”。我还不知道是什么原因造成的,但Firefox和Chrome也是如此。堆栈是PHP5.3、IIS6和FastCGI。这不是PHP或DB/SQLSRV超时,因为我增加了这两个查询,而其他查询需要更长的时间才能反馈所

tl;dr:在等待SQL查询执行时,是否可以定期向浏览器返回一些“虚拟空间”?这意味着在没有返回任何内容时,浏览器不会挂断

长话短说:

我制作了一个针对数据库的小型“web工具”(MS SQL,使用他们的PDO驱动程序)

有时,我运行的查询需要很长时间

大约100秒后,浏览器停止“旋转”。我还不知道是什么原因造成的,但Firefox和Chrome也是如此。堆栈是PHP5.3、IIS6和FastCGI。这不是PHP或DB/SQLSRV超时,因为我增加了这两个查询,而其他查询需要更长的时间才能反馈所有结果。(我可以通过写一些页眉重现问题,冷却110秒,然后写页脚。然后只显示页眉部分。)

当前查询的问题是,它在大约200秒的时间内没有反馈任何信息,然后整个查询就完成了。但当堆栈中的某些内容在大约100秒后停止侦听/接收/发送时,这并没有帮助


因此,问题是:在脚本等待SQL返回时,是否可以向浏览器提供一些虚拟空间?在我的母语Java中,这很简单,但在PHP中,这完全是单线程的(实际上是“单进程”)。我知道这种涓涓细流会起作用,因为我还有其他脚本,它们总共需要更长的时间,但会不断地将结果的一小部分发送回浏览器-这会很好地呈现出来。

PHP不会在您回显时将输出发送到浏览器。它将内容写入缓冲区,并立即将整个内容发送到浏览器。因此,不可以,您不能将输出滴流到浏览器。

PHP不会在您回显时将输出发送到浏览器。它将内容写入缓冲区,并立即将整个内容发送到浏览器。因此,不可以,您不能将输出滴流到浏览器。

如果您只想运行一个查询,则不能。但是,根据查询的性质,您可能只需将其拆分为多个较小的查询,然后循环执行这些查询

与您的其他回答和评论相反,如果您的通话中断,您可以将数据“滴流”到浏览器中。您正在寻找
flush()
函数

演示

<?php

for ($i = 0; $i <= 200; $i++)
{
    sleep(1);
    echo ' ';

    flush();
}

echo 'It worked!';
?>


试着运行这个。应该需要200秒。但是,由于存在
flush()
,它将在循环的每次迭代后向浏览器发送数据,希望不会超时!我老板的web主机在30秒不活动(Rackspace,grrrr!)后超时,因此我不得不无数次使用同样的技巧。

如果您只想运行一个查询,则不会。但是,根据查询的性质,您可能只需将其拆分为多个较小的查询,然后循环执行这些查询

与您的其他回答和评论相反,如果您的通话中断,您可以将数据“滴流”到浏览器中。您正在寻找
flush()
函数

演示

<?php

for ($i = 0; $i <= 200; $i++)
{
    sleep(1);
    echo ' ';

    flush();
}

echo 'It worked!';
?>


试着运行这个。应该需要200秒。但是,由于存在
flush()
,它将在循环的每次迭代后向浏览器发送数据,希望不会超时!我老板的web主机在30秒不活动(Rackspace,grrrr!)后超时,所以我不得不无数次地使用同样的技巧。

flush工作不太好有更好的方法-你可以将输出传输到一个文件,然后使用一个独立的php脚本只删除最后一行,然后在客户端上使用ajax,在最后一行每隔200毫秒轮询一次独立脚本。这给了你想要的效果,我现在正在处理它,我会在这里准备好代码


编辑1:哈哈,是你 flush的工作不是很好,有一种更好的方法——你可以将输出通过管道传输到一个文件,然后使用一个独立的php脚本只删除最后一行,然后在客户端上使用ajax每隔200毫秒轮询一次独立脚本。这给了你想要的效果,我现在正在处理它,我会在这里准备好代码


编辑1:哈哈,是你!不,PHP不是多线程的。数据库查询函数调用将阻止脚本,直到查询返回数据或整个事件超时。使用PHP无法启动另一个线程来允许这种涓涓细流。@MarcB,但您可以缓冲输出。@NathanelHermett:缓冲也会阻止输出。事实上,对于“涓流”更新,您希望禁用缓冲,以便尽快将任何输出发送到客户端。啊,我写错了。您可以刷新输出缓冲区。:)@马尔克:谢谢你的评论,但我相信这个问题暗示我知道问题的实质。我想知道我没有想过的任何把戏!不,PHP不是多线程的。数据库查询函数调用将阻止脚本,直到查询返回数据或整个事件超时。使用PHP无法启动另一个线程来允许这种涓涓细流。@MarcB,但您可以缓冲输出。@NathanelHermett:缓冲也会阻止输出。事实上,对于“涓流”更新,您希望禁用缓冲,以便尽快将任何输出发送到客户端。啊,我写错了。您可以刷新输出缓冲区。:)@马尔克:谢谢你的评论,但我相信这个问题暗示我知道问题的实质。我想知道我没有想过的任何把戏!感谢您的回答,但我特别指出,我确实知道如何使用浏览器问题是,我希望在保持浏览器正常运行的同时执行长时间运行的SQL。我无法拆分SQL。这里有一种方法:让主脚本“URL请求”另一个脚本执行长时间运行的任务。从th进行定时读取