技术控

    今日:136| 主题:49552
收藏本版 (1)
最新软件应用技术尽在掌握

[其他] PHP 远程文件下载的进度条实现

[复制链接]
╰素颜乜倾城° 发表于 2016-11-27 14:21:57
112 3

立即注册CoLaBug.com会员,免费获得投稿人的专业资料,享用更多功能,玩转个人品牌!

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
原文地址: https://prinzeugen.net/implem...
   PHP 实现远程下载文件到服务端并不是什么新鲜玩意,用 cURL 、 file_get_contents 、 fopen 等都能够轻易实现。
  但是这几种常规的方法都是在一个线程内下载文件,等文件下载完毕以后才能返回 HTTP 响应。所造成的结果就是用户在页面上点击「下载到服务器」按钮后,会看到空白页和加载的小菊花转啊转,转好久之后才出现「下载成功」的页面。
   当然,我上面所举例的情况是只使用纯粹的表单 POST 发送请求的情况。现在的话就算再不济也一般会使用 ajax 发送请求,然后在前台放个加载动画,等收到下载成功的回应之后再进行下一步操作。
   但是!即使是去掉了恶心的且需要等待的空白页,这样做还是对用户体验有不好的影响。没有具体的下载进度,只有一个一直转呀转的菊花图,估计挺多用户都无法坐和放宽吧
    (至少对于我来说是这样的)   而我一个 PHP 项目的一键更新系统正好需要重构,遂研究了如何在 PHP 作为后端时显示远程文件下载进度条,并捣鼓出了个像样的解决方案,在这里分享一下。
  0x01 原理

   也许你在搜索「PHP 下载 进度条」的时候会看到有些文章使用 PHP 的输出控制函数( flush 之类的)控制缓冲区来实现进度条。但是——
  那都是狗屁!

   没有人可以保证用户的 PHP 关闭了默认开启的 output buffering ,也无法保证 浏览器 / Web Server 不对脚本输出进行缓存。如果上述两者其中之一处于开启状态的话,你就会喜闻乐见的发现本应该慢慢增长的进度条会在等待完漫长的 xx 秒后一下子蹦到 100%_(因为控制前端进度条长度的语句被缓存起来,在脚本执行结束后一并发送了,而不是一块一块地传给浏览器)_。
  关于上面缓冲区控制的进度条就是辣鸡的更多讨论可以查看文章底部的参考链接。
  闲话休提。那么我们该如何实现下载进度条的更新呢?
  首先通过后端一点点输出控制进度条语句的方案已经 PASS 了,那么我们很自然的就会想到——
  在前端设置一个定时器,Ajax 轮循下载进度并更新页面上的进度条。

  0x02 概述

  知道了原理之后,我们先来考虑下整体的架构与步骤。
  
       
  •   用户点击「下载」按钮,前端展示出进度条,并 ajax 发送 prepare-download 的请求;
       
  •   后端收到请求,进行远程下载的准备工作 —— 准备好远程文件链接、临时文件存放位置以及 文件的大小 ,并返回给浏览器;
       
  •   前端拿到文件大小等信息后,发送真正的 start-download 请求(这个请求耗时可能会很长),并 启动轮循的计时器
       
  •   计时器启动后,每隔一段时间发送 get-file-size 请求,获取当前临时文件的大小, 计算进度 后更新进度条;
       
  • 直到下载完成。
      
  下面给出前后端代码的实例。
  0x03 后端

  代码照例放在 Gist 上,加载不出自行解决:
   " rel="nofollow,noindex" target="_blank">https://gist.github.com/print...
  0x05 效果 & 总结

   
PHP 远程文件下载的进度条实现-1 (文件下载,解决方案,下载文件,下一步,服务器)

   实例代码用了 fopen 和循环 fwrite 写入一个 chunk 的数据到临时文件,这是借鉴了 KODExplorer 远程下载的函数,在此致谢。另外也有通过 curl_setopt($ch, CURLOPT_FILE, $fp); 给 cURL 设置一个文件句柄的方法,但是我没有测试成功,希望各位也能试一试。
  以上。
  参考链接

  
       
  •   PHP: flush - Manual 的「说明」部分
       
  •   PHP progress bar - PHP Coding Help - PHP Freaks
       
  •   What is output buffering? - Stack Overflow
       
  •   KODExplorer/file.function.php at master
      

友荐云推荐




上一篇:利用封装、继承对Java代码进行优化
下一篇:周末到了,来段代码压压惊
酷辣虫提示酷辣虫禁止发表任何与中华人民共和国法律有抵触的内容!所有内容由用户发布,并不代表酷辣虫的观点,酷辣虫无法对用户发布内容真实性提供任何的保证,请自行验证并承担风险与后果。如您有版权、违规等问题,请通过"联系我们"或"违规举报"告知我们处理。

Everything 发表于 2016-11-30 23:21:24
低调奢华有内涵的╰素颜乜倾城°
回复 支持 反对

使用道具 举报

uesprvpq 发表于 5 天前
听说兔子做版主了?
回复 支持 反对

使用道具 举报

wmg1973 发表于 3 天前
报,报,报,报,报告楼主,我来了!
回复 支持 反对

使用道具 举报

*滑动验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

我要投稿

推荐阅读

扫码访问 @iTTTTT瑞翔 的微博
回页顶回复上一篇下一篇回列表手机版
手机版/CoLaBug.com ( 粤ICP备05003221号 | 文网文[2010]257号 )|网站地图 酷辣虫

© 2001-2016 Comsenz Inc. Design: Dean. DiscuzFans.

返回顶部 返回列表