0

tl;dr: Is it possible to feed some "dummy spaces" periodically back to the browser while waiting for a SQL query to execute? This to not have the browser hang up on me while nothing returns.

Longer story:

I've made a small "web tool" against a database (MS SQL, using their PDO driver).

Sometimes, the queries that I run take a long time.

After about 100 seconds, the browser just stops "rotating". I don't know yet what causes this, but it is the same with Firefox and Chrome. The stack is PHP 5.3, IIS 6, FastCGI. It is not PHP nor DB/SQLSRV timeout, as I've increased both of those - and other queries I have take a longer time to feed back all the result. (I can reproduce the problem by writing some header, chilling for 110 seconds, and then write the footer. Only the header-part is then shown.)

The problem with the present query, is that it doesn't feed back anything for about 200 seconds, then the whole thing comes. But this doesn't help when something along that stack have stopped listening/receiving/transmitting after about 100 seconds.

Thus, the question: Is it possible to trickle-feed the browser some dummy spaces while the script is waiting for the SQL to return? In my native tounge of Java, this would be trivial, but in PHP, one is AFAIK utterly single threaded (actually, "single process'd"). I know that this trickling would work, as I have other scripts that in total takes much longer, but which continually sends small pieces of the result back to the browser - this renders just fine.

4

3 回答 3

2

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

与您的其他答案和评论相反,如果您拆分呼叫,您可以将数据“滴灌”到浏览器。您正在寻找flush()功能。

演示

<?php

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

    flush();
}

echo 'It worked!';
?>

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

于 2012-08-08T19:09:24.307 回答
1

当您回显它时,PHP 不会将输出发送到浏览器。它将内容写入缓冲区,并立即将全部内容发送到浏览器。所以,不,你不能将输出涓涓细流到浏览器。

于 2012-08-08T19:01:19.970 回答
0

flush 不能很好地工作有一个更好的方法-您可以将输出通过管道传输到文件,然后使用独立的 php 脚本仅翻录最后一行,然后在客户端上使用 ajax 每 200 毫秒轮询一次该独立脚本最后一行。这给出了你想要的效果

EDIT1:哈哈恩德是你!<3 来自英格兰,你最讨厌你 x

EDIT2:超时来自 PHP.ini 内外的大量微妙参数,大部分没有记录,因为它们似乎无关,但也不要低估浏览器的跛脚 - 根据我的经验,我只能辐射完全超时一次,然后才在 Firefox 上,但我能够以这种方式运行/轮询一个 3 小时长的脚本(遗憾的是,这是一个 AD 迁移脚本,在我的旧工作中,我没有代码)

EDIT3:您可以通过使用 PHP CLI 然后进程 ID 或使用 curl 在 PHP 中“线程化”两者都相当 ewww 但你可以做到

于 2014-01-07T11:32:39.797 回答