热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PHP文件上传进度的实现原理

uploadprogress扩展需要依靠JS获取服务器提供的进度,这里的进度是服务器接收的文件进度。

uploadprogress扩展需要依靠JS获取服务器提供的进度,这里的进度是服务器接收的文件进度。

而在PHP5.4之后,我们可以在不添加扩展的情况下,从session数据中获取了文件上传的进度。uploadprogress扩展和PHP5.4的session扩展都能获取上传的进度,其是否有相同的地方呢?

我们先来看uploadprogress扩展,下载源码包,解圧,直接打开文件,我们可以在example中找到一个简单的示例。在info.php文件中,uploadprogress_get_info函数用来获取上传文件进度。upploadprogress.c文件存储了扩展的实现过程。uploadprogress扩展实现的关键在于其模块寝化函数:

1
2
3
4
5
6
7
PHP_MINIT_FUNCTION(uploadprogress)
{
    REGISTER_INI_ENTRIES();
    php_rfc1867_callback = uploadprogress_php_rfc1867_file;
       
    returnSUCCESS;
}

此函数的核心就是设置php_rfc1867_callback为uploadprogress_php_rfc1867_file。

设置这个函数指针有什么用呢?

在前面的文章PHP内核中文件上传类型的获取过程中我们了解到PHP处理POST请求的函数是SAPI_POST_HANDLER_FUNC(rfc1867_post_handler)(main/rfc1867.c)。在这里, 我们发现了若干个php_rfc1867_callback的调用,从调用的第一个参数来看,它可以分为六个事件,或者说有六个回调更新点。

如果此时我们查看PHP5.4的的session扩展的实现文件session.c时,搜索php_rfc1867_callback,你会发现在模块初始化函数中也有与扩展类似的赋值操作:


1
php_rfc1867_callback = php_session_rfc1867_callback;

同样,在php_session_rfc1867_callback函数中有与uploadprogress同样的六个事件的处理,这六个事件相当于六个钩子程序,分别对应POST请求的处理的六个不同的位置,在PHP5.4中他们的作用分别是:


1、MULTIPART_EVENT_START 在处理所有的请求实体之前,初始化上传进度信息,比用于记录上传进度相关信息的progress结构体信息(如content-length)


2、MULTIPART_EVENT_FORMDATA 对于每个multipart包含的控制,执行此步初始化操作,以此之前会解析Content-Disposition相关属性,并初始化progress的其它信息,如session_id,以及整个上传活动的key,这里表示整个上传进度准备好了。


3、MULTIPART_EVENT_FILE_START 开始处理上传的文件信息,如果progress的data不存在,则会创建此结构,并初始化session中存储的对于此次文件上传的start_time、content_length、bytes_processed、files等信息。然后处理单个文件的上传属性,如field_name、tmp_name等。对于tmp_name等字段这里是执行初始化操作。这一步的时候获取session 的值才会开始有上传进度的相关信息。


4、MULTIPART_EVENT_FILE_DATA 更新上传文件的长度,在一堆的文件相关信息检测和临时文件写入之前,也是在将数据写入到$_FILES之前。


5、MULTIPART_EVENT_FILE_END 单个文件上传结束,此时会更新这个文件相关的一些信息,比如error, tmp_name,tmp_name字段在start时是null。当然这里还有针对当前文件的done字段的更新。

6、MULTIPART_EVENT_END 更新session数组的最后的一些结信息 比如done字段 并清空progress的信息,

这里的六个事件是相同的,而uploadprogress扩展和PHP5.4的session扩展在事件处理过程中中间存储结构和最后的返回内容与方式上存在一些差异。uploadprogress扩展的存储结构为一个按照扩展制定的规则生成的临时文件,最后是通过扩展函数uploadprogress_get_info返回上传进度的数组。PHP5.4的存储结构为SESSION的存储方式,或者是文件,或者是memcache,这个按session的设置来,其最终是通过$_SESSION返回相关数组。


除了uploadprogress扩展外,APC也以设置php_rfc1867_callback = apc_rfc1867_progress,提供了类似的解决方案,启动此功能需要在php.ini中设置apc.rfc1867项为启用,并且在表单中加一个隐藏域 APC_UPLOAD_PROGRESS,这个域的值可以随机生成一个hash,以确定此次上传操作的唯一性。通过Ajax调用服务端显示进度的接口,在接口中通过apc_fetch函数获取APC缓存的文件上传进度。比如print_r(apc_fetch(”upload_$_POST[APC_UPLOAD_PROGRESS]“));可以得到如下结果:

1
2
3
4
5
6
7
8
9
10
11
Array
(
    [total] => 1142543
    [current] => 1142543
    [rate] => 1828068.8
    [filename] => test
    [name] => file
    [temp_filename] => /tmp/php8F
    [cancel_upload] => 0
    [done] => 1
)

推荐阅读
  • 探讨了如何解决Ajax请求响应时间过长的问题。本文分析了一个从服务器获取少量数据的Ajax请求,尽管服务器已经对JSON响应进行了缓存,但实际响应时间仍然不稳定。 ... [详细]
  • 本文详细介绍了如何使用PHP检测AJAX请求,通过分析预定义服务器变量来判断请求是否来自XMLHttpRequest。此方法简单实用,适用于各种Web开发场景。 ... [详细]
  • 理解文档对象模型(DOM)
    本文介绍了文档对象模型(DOM)的基本概念,包括其作为HTML文档的节点树结构,以及如何通过JavaScript操作DOM来实现网页的动态交互。 ... [详细]
  • 本文介绍如何解决在 IIS 环境下 PHP 页面无法找到的问题。主要步骤包括配置 Internet 信息服务管理器中的 ISAPI 扩展和 Active Server Pages 设置,确保 PHP 脚本能够正常运行。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 深入理解Cookie与Session会话管理
    本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • 本文探讨了在不使用服务器控件的情况下,如何通过多种方法获取并修改页面中的HTML元素值。除了常见的AJAX方式,还介绍了其他可行的技术方案。 ... [详细]
  • 本文详细介绍了中央电视台电影频道的节目预告,并通过专业工具分析了其加载方式,确保用户能够获取最准确的电视节目信息。 ... [详细]
  • 本文介绍了多个关于JavaScript的书籍资源、实用工具和编程实例,涵盖从入门到进阶的各个阶段,帮助读者全面提升JavaScript编程能力。 ... [详细]
  • 当unique验证运到图片上传时
    2019独角兽企业重金招聘Python工程师标准model:public$imageFile;publicfunctionrules(){return[[[na ... [详细]
  • 一个登陆界面
    预览截图html部分123456789101112用户登入1314邮箱名称邮箱为空15密码密码为空16登 ... [详细]
  • 本文详细介绍了如何利用Go语言和WebSockets技术构建一个高效的实时聊天系统。随着网络应用的日益复杂化,实时交互成为了提升用户体验的关键要素之一。通过本指南,开发者可以学习到最新的技术和最佳实践。 ... [详细]
  • 本文探讨了2019年前端技术的发展趋势,包括工具化、配置化和泛前端化等方面,并提供了详细的学习路线和职业规划建议。 ... [详细]
  • 本文深入探讨了JavaScript中实现继承的四种常见方法,包括原型链继承、构造函数继承、组合继承和寄生组合继承。对于正在学习或从事Web前端开发的技术人员来说,理解这些继承模式对于提高代码质量和维护性至关重要。 ... [详细]
author-avatar
Dark-胡俊賢
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有