PHP进度条
2020-01-07 本文已影响0人
江河湖海琴瑟琵琶
假设用户上传一个100行文件,PHP遍历写入数据库,并且显示当前执行的百分比.
for($i=1;$i<+100;$i++){
sleep(1); #假设这是特别耗时的语句
//输出百分比
echo $i.'--';
}
正常情况下,PHP有个自己的输出缓冲区,output_buffer,默认4K
图片.png
当PHP脚本中输出内容,echo,dump等
会把内容写到PHP自己的缓冲区,等脚本执行结束或者缓存达到上限后,再把内容放到服务器(Nginx)的缓冲区,服务器根据配置,把内容发送给客户端.
比如echo '张三'; 张三会经历以下过程:
'张三' => PHP缓冲区 => 服务器缓冲区 =>浏览器
所以上边的代码,服务器会等脚本执行结束后,一次性输出1-100到浏览器.要是数据量大的话,PHP处理不完,就不会返回,而浏览器一直处于等待服务器返回的状态,页面就会卡住.
现在想要的是,像进度条一样.每循环一次,向浏览器发送一次百分比,让用户能看到执行进度.
NGINX环境:
set_time_limit(0); //防止页面超时
ignore_user_abort(true); //设置浏览器断开连接继续执行
header('X-Accel-Buffering: no'); //关闭buffer,apache不用加
header('Content-type: text/html;charset=utf-8'); //设置网页编码
ob_end_clean(); //清空并关闭PHP的缓冲区
for($i=1;$i<=100;$i++){
sleep(1);#假设这是比较耗时的语句
echo $i.'--';//输出,由于PHP缓冲区已经关闭,内容会直接放进服务器缓冲区
flush();//强制刷新服务器缓冲区,发送数据到浏览器
}
主要是两个函数:ob_end_clean()和flush().
ob_end_clean(); 关闭并清空PHP自身的缓冲区,如果缓冲区中有数据,数据将被抛弃.
flush();强制服务器发送缓冲区中的内容到浏览器,
PHP脚本中输出的内容会直接进入到服务器缓冲区,
每次循环完成后,flulsh,强制把服务器缓冲区中的内容发送到浏览器
唯一的问题是,IOS手机的浏览器达不到效果,安卓却正常.原因不明,有时间再研究