PHP实现前台同步显示后台任务进度
无    20    0    0
libi

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

<?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标记)同样会进行缓存,找到问题所在后尝试以下代码;

<?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中提出出来的安装进度代码供大家参考吧

Discuz! 安装向导

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; }





function showmessage(message) {
	document.getElementById('notice').innerHTML += message + '';
	document.getElementById('notice').scrollTop = 100000000;
}

		
showmessage(\''.addslashes($message).' \');'."\r\n";
	flush();
	ob_flush();
}

 


文档导航