2009-11-08 126 views
0

我试图找到一种方法让PHP向浏览器指示所有页面输出已完成。页面完成后,我们正在运行一些统计代码,通常不需要很长时间,但万一它不希望让用户浏览器等待更多数据。这不能通过JavaScript完成,因为它需要与手机一起工作。PHP输出完成通知

我已经开始使用

mb_http_output("UTF8"); 
ob_start("mb_output_handler"); 

,以确保我没有问题,我的网站MB的文本(日本)输出缓冲。我希望ob_end_flush()能做到这一点,但如果我放置睡眠(10);在ob_end_flush()之后浏览器等待另外10秒。有没有人对此有任何想法?

UPDATE: 使用抖动接近下面我“ob_gzhandler”得到它用gzip工作的任何一个看到任何可能出现的问题吗?

//may be also add headers for cache-control and expires (IE) 
header("Connection: close"); //tells browser that connection will be closed 
ob_start(); 
ob_start("ob_gzhandler"); 
//page content 
ob_end_flush(); 
$size = ob_get_length(); 
header("Content-Length: $size"); 
ob_end_flush(); 
flush(); 

再次更新:

请再看一下上面的代码。你需要做一个ob_start();在ob_start(“ob_gzhandler”)之前;然后调用ob_end_flush();在调用ob_get_length()之前,以便获得正确的gzip压缩大小。

回答

0

使用的东西沿着这些线路

//may be also add headers for cache-control and expires (IE) 
header("Connection: close"); //tells browser that connection will be closed 
ob_start(); 
//generate your output 
$size = ob_get_length(); 
header("Content-Length: $size"); 
ob_end_flush(); 
flush(); 
//continue statistic processing 
+0

我试过这个,如果我添加一些像睡觉(20);在flush()之后;浏览器(FireFox 3.5)仍然显示加载指示器20秒。 – AWinter 2009-11-08 11:45:53

+0

我终于得到了这个工作,但只有当我包含标题(“Content-Encoding:none”);在标题下方(“Connection:close”);任何想法为什么这可能是? – AWinter 2009-11-08 13:17:25

+0

有关如何使用out设置标题(“Content-Encoding:none”)工作的任何想法;我宁愿保持gzip在可能的情况下运行 – AWinter 2009-11-08 13:20:50

0

我不认为有一种方式来通知输出完成,至少从发送输出脚本的浏览器。如果您使用其他脚本来监控第一个脚本的输出并使用iframe,那么您可能可以做到这一点。

浏览器知道当页面被认为已加载时输出完成。这就是浏览器所知道的。

0

你可以在后台创建一个新的php进程并让它处理统计信息。喜欢的东西: shell_exec('php stats.php &');

的&末可以确保它在后台运行,所以即使stats.php需要20秒,游客将不会注意到它。 你可能需要将数据传递到统计数据的脚本,您可以通过传递参数,这样做:

shell_exec('php stats.php -b '. escapeshellarg($_SERVER['HTTP_USER_AGENT']) .' &');

在stats.php,你会使用变量来获取数据。

但是我不会这样做,如果统计信息代码不需要那么长时间就可以运行,因为为每个页面加载分配一个新进程会造成一些开销。我不知道这是什么让统计代码需要很长时间来处理,但另一种解决方案可能是将原始数据插入到数据库中,并让后台作业处理该数据以创建可用的统计数据。这可以通过cron作业完成,也可以通过在处理队列的无限循环中运行屏幕来完成。

+0

在PHP中,如果您希望新进程在后台运行,您还必须重定向stdout,例如, 'shell_exec('php stats.php>/dev/null &');' – 2009-11-08 12:37:58

+0

真的,忘了这个,也可能把stderr指向stdout,然后直接输出到/ dev/null。 – 2009-11-08 14:43:34

0

尝试将统计代码移到单独的函数中,并在dom中使用ajax调用此函数。在呈现的页面上的JavaScript代码准备或onload事件就像这个荟萃代码:

<html> 
    <script type="text/javascript"> 
    dom.onready = Ajax.call(location.href + '?do_stats'); 
    </script> 
    <body>... 
</html> 

的dom.ready事件可以通过jQuery的或原型库提供。缺点是它只会在启用js的情况下工作。

或者,您可以将统计信息的所有必需信息记录到数据库,然后派发脚本收集排队数据并在后台对其进行处理 - 例如使用cron。

+0

不幸的是,大多数日本手机都没有不支持JavaScript,在日本尤其是他们通常可以占用户总数的50%或更多 – AWinter 2009-11-08 13:56:56

+0

好的,你的问题中缺少那个重要的一点,你应该修改它 – hurikhan77 2009-11-08 14:02:43

+0

我没忘记提及。 – AWinter 2009-11-08 14:11:08