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,强制把服务器缓冲区中的内容发送到浏览器

效果如下: 图片.png

唯一的问题是,IOS手机的浏览器达不到效果,安卓却正常.原因不明,有时间再研究

上一篇下一篇

猜你喜欢

热点阅读