- 本文地址: https://www.laruence.com/2011/10/10/2217.html
- 转载请注明出处
文件上传进度反馈, 这个需求在当前是越来越普遍, 比如大附件邮件. 在PHP5.4以前, 我们可以通过APC提供的功能来实现. 或者使用PECL扩展uploadprogress来实现.
虽然说, 它们能很好的解决现在的问题, 但是也有很明显的不足:
- 1. 他们都需要额外安装(我们并没有打算把APC加入PHP5.4)
- 2. 它们都使用本地机制来存储这些信息, APC使用共享内存, 而uploadprogress使用文件系统(不考虑NFS), 这在多台前端机的时候会造成麻烦.
从PHP的角度来说, 最好的储存这些信息的地方应该是SESSION, 首先它是PHP原生支持的机制. 其次, 它可以被配置到存放到任何地方(支持多机共享).
正因为此, Arnaud Le Blanc提出了针对Session报告上传进度的RFC, 并且现在实现也已经包含在了PHP5.4的主干中.
这个新特性, 提供了一些新的INI配置, 他们和APC的相关配置很类似:
- session.upload_progress.enabled[=1] : 是否启用上传进度报告(默认开启)
- session.upload_progress.cleanup[=1] : 是否在上传完成后及时删除进度数据(默认开启, 推荐开启).
- session.upload_progress.prefix[=upload_progress_] : 进度数据将存储在_SESSION[session.upload_progress.prefix . _POST[session.upload_progress.name]]
- session.upload_progress.name[=PHP_SESSION_UPLOAD_PROGRESS] : 如果_POST[session.upload_progress.name]没有被设置, 则不会报告进度.
- session.upload_progress.freq[=1%] : 更新进度的频率(已经处理的字节数), 也支持百分比表示'%'.
- session.upload_progress.min_freq[=1.0] : 更新进度的时间间隔(秒级)
对于如下的上传表单:
<form action="upload.php" method="POST" enctype="multipart/form-data"> <input type="hidden" name="<?php echo ini_get("session.upload_progress.name"); ?>" value="laruence" /> <input type="file" name="file1" /> <input type="file" name="file2" /> <input type="submit" /> </form>
如果我们上传一个足够大的文件(网速要是足够慢就更好:P), 我们就可以从_SESSION中, 得到类似下面的进度信息:
$_SESSION["upload_progress_laruence"] = array( "start_time" => 1234567890, // 请求时间 "content_length" => 57343257, // 上传文件总大小 "bytes_processed" => 453489, // 已经处理的大小 "done" => false, // 当所有上传处理完成后为TRUE "files" => array( 0 => array( "field_name" => "file1", // 表单中上传框的名字 // The following 3 elements equals those in $_FILES "name" => "foo.avi", "tmp_name" => "/tmp/phpxxxxxx", "error" => 0, "done" => true, // 当这个文件处理完成后会变成TRUE "start_time" => 1234567890, // 这个文件开始处理时间 "bytes_processed" => 57343250, // 这个文件已经处理的大小 ), // An other file, not finished uploading, in the same request 1 => array( "field_name" => "file2", "name" => "bar.avi", "tmp_name" => NULL, "error" => 0, "done" => false, "start_time" => 1234567899, "bytes_processed" => 54554, ), ) );
这个是不是很方便呢?
但是还是要提醒一下, PHP 5.4还处于开发阶段, 在最终release之前, 任何新特性都可能被调整或者更改. 如果大家有任何建议, 也欢迎反馈, 帮助我们使得PHP变得更好.
谢谢
Johannes的blog也介绍过: http://schlueters.de/blog/archives/151-Upload-Progress-in-PHP-trunk.html
更多更新信息, 请关注: Changelog
good..
试了下,没打印出数组,哈哈
我的个人资料很棒,我已经回答了很多问题,也有很多喜欢的人。
不错,实验一下,PHP7应该也支持吧!
[…] 本文地址: http://www.laruence.com/2011/10/10/2217.html […]
当自定义session存储的时候,比如用redis存储session,这时候无论如何也无法取到进度,php手册下面的note也有人反映此问题.
我记得这个问题的解释在微博里看到过, 但是鸟哥的微博删掉了, 不知道是否有人能告知鸟哥微博的解释? 或者鸟哥能否发一下您当时的解释?
这个问题是我提的, 鸟哥在微博回复过此问题的解决办法, 有一天我想找这个解决办法发现鸟哥把微博全部删光了, 于是好久也找不出原因. 直到前几天整理微信聊天记录, 发觉我当年把鸟哥的解决方法记录在微信里了, 现在把此问题解决方法贴出来以供有同样问题的人查询:
PHP7的session upload progress(上传进度)在其他session handler(非文件)的时候不能正常工作,
原因是如果PHP是以fastcgi的方式运行, 需要关闭nginx的request buffering功能:
proxy_request_buffering off;
fastcgi_request_buffering off;
那在上传文件的时候 写session是每隔多久写一次呢 要在前端显示的话 那就直接用ajax每隔一定时间去轮训后台脚本 后台脚本再去读取session吗
我没有打印出session数组
我没有打印出那个session数组
What i do not realize is actually how you are not really
much more well-appreciated than you may be now.
You’re very intelligent. You understand thus considerably
with regards to this topic, made me personally imagine it from a lot of varied angles.
Its like men and women are not interested except it is something to do with Girl gaga!
Your individual stuffs nice. At all times take care of it up!
Pretty nice post. I simply stumbled upon your weblog and wished to mention that
I’ve truly loved surfing around your blog posts. In any case
I’ll be subscribing to your rss feed and I’m hoping you write again very soon!
session.upload_progress
在apache下使用没问题,但是在nginx+php的环境,只有文件上传完成之后才会写入$_SESSION, 而此时如果设置了
session.upload_progress.cleanup[=1]
session里的值又会被清除,所以一直无法显示出来。
HTML5 对上传文件进行了重新设计,现在已经可以完全基本客户端自身完成上传进度的展示了。
遗憾的是现代浏览器还没有太好的普及,但这仅是一个时间问题,这样一来,PHP 的靠 SESSION 实现的上传进度探测就相对低效很多,且实现较好的体验也相对困难些。
bytes_processed
文件已处理的大小怎么写?
bytes_processed=?
这个处理进度应该等于什么?
[…] 本文地址: http://www.laruence.com/2011/10/10/2217.html […]
这个功能太实用了!
[…] 参考:http://www.laruence.com/2011/10/10/2217.html […]
php-5.4.0RC7-Win32-VC9-x86.zip下测试是支持的,是我的方法不对,现在解决了
你好,我在php-5.4.0RC7-Win32-VC9-x86.zip下测试此特性貌似不管用哦????
方便
这个好!!
有原生支持就比较好了。
这功能太实用了!
cool
也可以用 NGINX 的扩展支持,好处是上传时不会消耗 PHP 进程。
这个就太帅了~~~ 哈哈哈