我正在使用php编写一个API来包装网站功能并返回json \ xml中的所有内容。我一直在使用curl,到目前为止它的工作效果很好。 该网站有一个标准的文件上传帖子,可接受高达1GB的文件。
所以问题是如何将文件上传流重定向到通讯网站?
我可以下载该文件,然后上传它,但我的服务器仅限于20MG。这似乎是一个糟糕的解决方案。
甚至可以控制流并将其直接重定向到网站吗?
答案 0 :(得分:2)
我保留了底层的原始版本,但事实证明,有一种方法可以做到这一点
您需要使用的是HTTP put方法(遗憾的是在本机浏览器表单中不可用),PHP php://input
包装器和流式php Socket的组合。这有几个限制 - PHP不允许发布数据php://input
,但它对PUT filedata没有任何作用 - 聪明!
如果您要使用apache尝试此操作,则需要安装mod_actions
已激活。您还需要在virtualhost / .htaccess中使用PUT
指令指定Script
脚本。
http://blog.haraldkraft.de/2009/08/invalid-command-script-in-apache-configuration/
这允许put方法仅用于一个url端点。这是将打开套接字并将其数据转发到其他位置的文件。在下面的示例中,这只是index.php
我已经使用python请求模块准备了一个这样的样板示例,作为客户端使用图像文件发送put请求。如果您运行remote_server.py
,它将打开一个只侦听端口的服务,并等待来自php的转发消息。 put.py
将实际的put请求发送给PHP。您需要将主机put.py
和index.php
设置为您在虚拟主机中定义的主机,具体取决于您的设置。
运行put.py
将打开包含的图像文件,将其发送到您的php虚拟主机,然后它将打开一个套接字并将接收的数据流式传输到python伪服务并将其打印到stdout中终点站。流式传输PHP转发器!
没有什么可以阻止您使用以相同方式侦听TCP端口的任何远程服务,完全使用另一种语言。客户端可以以相同的方式重写,只要它可以发送PUT请求。
完整的例子在这里:
https://github.com/DeaconDesperado/php-streamer
我真的对这个问题很开心。请让我知道它是如何工作的,我们可以一起打补丁。
开始原始回答
在php中没有本地方式异步传递文件,因为它与请求体一起传递而不以某种方式将其状态保存到光盘。这意味着您受服务器内存限制(20MB)的限制。收到请求后初始化$_FILES
超全局的方式取决于此,因为它会尝试将multipart
数据迁移到tmp目录。
使用套接字可以实现类似的东西,因为这至少会绕过HTTP协议,但是如果文件是在HTTP请求中传递的,那么php仍然会尝试将其保存在内存中之前什么都有它。你已经设置了流程的尾端而没有实际的方法来实现这一目标。
有Stream库接近,但仍然依赖于在服务器端读取内存中的文件 - 它必须已经那里。
您所描述的内容有点超出HTTP协议,特别是因为请求主体太大了。 HTTP是一种基于请求/响应的机制,一种依赖于另一种......在中间点完成就地流式上传非常困难,因为这意味着某些协议在流式传输时上传在
有人可能会认为这比HTTP的限制更多,并且由于PHP的设计是以HTTP协议为基础的,因此您正在其舒适区之外移动。
这样的部署经常尝试使用其他脚本语言取得巨大成功(例如,在Python中使用Twisted,很多人都在使用NodeJS来实现其并发设计模式,Ruby或Java中有很多我不太了解的选择。)