开发者社区> 问答> 正文

php 大文件 上传 流式处理:报错

出一个极端的场景,以突出问题的重点:

在局域网的高速网络环境中(不考虑传输时间),从WEB页面的表单传送一个很大的文件。

PHP要返回给用户这个文件的行数。

最合理的处理方式是PHP提供一个直接读取文件上传的网络数据流的接口,然后在PHP程序里一边接收浏览器上传的文件一边统计行数,收一点统计一点,统计行数这个根本用不了多少内存。等文件传输完了就直接把统计的行数返回给客户端。

以上最合理的处理方式对磁盘需求为0,对内存需求很少,应该是最优的了。

问题是:

PHP好像针对文件上传会自动缓存,要先保存到临时文件里,等传输完成了再让用户的代码执行。这样白白浪费了存储的磁盘空间,而且写一次磁盘后再取出来处理这一来一回时间浪费比较多。

所以想请问下各路大侠好汉,PHP有没有什么方法可以直接处理客户端的网络数据流的?这个在进行一些负载比较大的流式处理任务的开发过程中比较有用。

谢谢。

展开
收起
kun坤 2020-06-07 16:24:43 895 0
1 条回答
写回答
取消 提交回答
  • 这个似乎是没办法。

    看这段:

    在图片上传部分,其实能玩的花样很少,但是编写代码所消耗的时间最多。现在我们再假设一种情景,如果我们的图片服务器前端采用Nginx,上传功能 用PHP实现,需要写的代码很少,但是性能如何呢,答案是很差。首先PHP接收到Nginx传过来的请求后,会根据http协议(RFC1867)分离出 其中的二进制文件,存储在一个临时目录里,等我们在PHP代码里使用$_FILES["upfile"][tmp_name]获取到文件后计算MD5再存 储到指定目录,在这个过程中有一次读文件一次写文件是多余的,其实最好的情况是我们拿到http请求中的二进制文件(最好在内存里),直接计算MD5然后存储。 于是我去阅读了PHP的源代码,自己实现了POST文件的解析,让http层直接和存储层连在了一起,提高了上传图片的性能。关于RFC1867的内容和PHP是如何处理的,感兴趣的读者可以去搜索了解下,这里推荐@Laruence的文章《PHP文件上传源码分析(RFC1867) 》。 除了POST请求这个例子,zimg代码中有多处都体现了这种“减少磁盘I/O,尽量在内存中读写”和“避免内存复制”的思想,一点点的积累,最终将会带来优秀的表现。
    http://www.wingdevops.com/?p=291

    ######只能针对原始请求写一个HTTP处理程序了,用nginx路由过来单独处理。######大哥出手果然不同,就你知道我在乱七八糟说了些啥,哈哈。######php:input//######

    引用来自“大灰狼wow”的评论

    php:input//
    这个恰好对付不了上传文件的表单######这也算是一个思路,传文件的请求可以由应用程序发起纯POST的。######

    如果只是统计行数的话……为啥不直接用个flash解决

    ######要的效果是文件传给PHP,PHP统计出结果。这个是需求。 我说的最优方案是针对这个需求的。######

    楼主理解错了!

    上传文件第一步是 由 浏览器把 本地文件上传到服务器的临时文件夹,文件上传中,PHP操作文件的时候,文件已经传完了(此时文件在临时文件中),PHP只是把临时文件移动到上传目录,所以这个以web的方式来说是实现不了的。(根本原因是上传文件这个过程压根没PHP的事,传完了PHP才来做事)

    ######这位仁兄说得在理,看看其它看官怎么说。######html5不是允许将文件分片上传吗? 自己切割成5m一个的包呗。######mark######是这样,最近也遇到这样的问题,貌似php是无法读取到浏览器上传文件的文件流的,只能等浏览器把文件流传送到服务器,以临时文件保存,这时候php才去处理的。。。######

    引用来自“杨佰”的评论

    是这样,最近也遇到这样的问题,貌似php是无法读取到浏览器上传文件的文件流的,只能等浏览器把文件流传送到服务器,以临时文件保存,这时候php才去处理的。。。
    这个问题可能要绕过php了
    2020-06-07 16:24:48
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
PHP安全开发:从白帽角度做安全 立即下载
PHP 2017.北京 全球开发者大会——高可用的PHP 立即下载
复杂PHP系统性能瓶颈排查及优化 立即下载