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