PHP实现前台同步显示后台任务进度

一次批量发送几千条短信。 如果直接在后台循环执行虽然可行,但是前台操作用户就只能坐着空等,完全看不到后台执行结果,所以考虑能不能有一种办法可以在php后台执行过程中同时在前台显示后台执行任务进度呢。 但是这里遇到一个问题,一般情况下php都是在后台任务执行完毕后输出结果到浏览器,在执行过程不会给浏览器发送任何数据。这个时候想到了可以使用php的flush函数,可以使用flush函数在程序执行中强制输出; 尝试以下代码:

1
2
3
4
5
6
7
8
<?php
for ($i = 1; $i <= 50; $i++) {
 ob_flush();
 flush();
 echo $i.'<br/>';
 sleep(rand(0, 1));
}
?>

网上大都这样的例子,看代码应该会每隔一秒输出一个数字。但是大家实际测试下情况并非如此,而是和没用flush一样,一次性输出1-50; 在这里请大家参考下鸟哥博客上的一篇文章http://www.laruence.com/2010/04/15/1414.html( 深入理解ob_flush和flush的区别); 其中有一段话:

有些Apache的模块,比如mod_gzip,可能自己进行输出缓存,这将导致flush()函数产生的结果不会立即被发送到客户端浏览器。 

甚至浏览器也会在显示之前,缓存接收到的内容。例如 Netscape浏览器会在接受到换行或 html 标记的开头之前缓存内容,并且在接受到 </table> 标记之前,不会显示出整个表格。 

一些版本的 Microsoft Internet Explorer 只有当接受到的256个字节以后才开始显示该页面,所以必须发送一些额外的空格来让这
些浏览器显示页面内容。

所以找到问题所在了,不是因为flush没有起作用,而是服务器或者浏览器在内容不到一定的字节数(甚至是没有遇到html标记)同样会进行缓存,找到问题所在后尝试以下代码;

1
2
3
4
5
6
7
8
9
<?php
echo str_repeat("<b></br>",4096); //随便输出一段代码立即输出
for ($i = 1; $i <= 50; $i++) {
ob_flush();
flush();
echo $i.'<br/>';
sleep(rand(0, 1));
}
?>

已经可以将后台数据实时发送到前台了,然后有办法了吗?结合js,每次循环都输出一段js,去操作html节点;附上disucz中提出出来的安装进度代码供大家参考吧

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>Discuz! 安装向导</title>
<style type="text/css">
body{ padding:5px 0; background:#FFF; text-align:center; }
body, td, input, textarea, select, button{ color:#666; font:12px/1.5 Verdana, Tahoma, Arial, 'Microsoft Yahei', 'Simsun', sans-serif; }
.container{ overflow:hidden; margin:0 auto; width:700px; height:auto !important;text-align:left; border:1px solid #B5CFD9; }
.main{ padding:20px 20px 0; background:#F7FBFE url(bg_repx.gif) repeat-x 0 -194px; }
    .main h3{ margin:10px auto; width:75%; color:#6CA1B4; font-weight:700; }
#notice { overflow: hidden; margin: 20px; padding: 5px; height: 300px; border: 1px solid #B5CFD9; text-align: left; }
</style>
<meta name="Copyright" content="Comsenz Inc.">
</head>
<body><div>
<div><script type="text/javascript">
function showmessage(message) {
    document.getElementById('notice').innerHTML += message + '<br/>';
    document.getElementById('notice').scrollTop = 100000000;
}
</script>
        <div id="notice"></div>
<?php
//检测完成后显示的信息
function showjsmessage($message) {
    echo '<script type="text/javascript">showmessage(\''.addslashes($message).' \');</script>'."\r\n";
    flush();
    ob_flush();
}
 
//模拟初始化数据表
for ($i = 1; $i <= 50; $i++) {
    showjsmessage("建立数据表 {$i} ... 成功");
    sleep(rand(0, 1));
}
 
?>
</div>
</div>
</body>
</html>

posted on 2013-07-17 00:50  senly  阅读(1014)  评论(0编辑  收藏  举报

导航