2

问题

是否可以通过 PHP 流式传输上传文件,以便其他客户端可以在第一个客户端上传时下载它?

我不想将文件永久保存在服务器上。我怎样才能做到这一点?

为什么选择 PHP?

下载客户端不需要额外的软件来获取流。我认为最简单的方法是网络浏览器。

4

3 回答 3

3

这是可能的,但实施起来会相当尴尬。主要障碍是多部分 POST 请求的处理被硬编码到 PHP 中。在调用您的脚本之前,它将始终将文件保存到临时位置。一种解决方法是将 PHP-CLI 设置为 CGI 脚本。由于 PHP 的 CLI 版本不支持 HTTP,因此它可以让您掌握传入的数据。

.CGI 文件将如下所示:

#!/usr/local/src/php-4.3.4/sapi/cli/php
<?php

// populate $_GET
parse_str($_ENV['QUERY_STRING'], $_GET);

// get the session id from the cookie
parse_str($_ENV['HTTP_COOKIE'], $_COOKIE);
$session_name = ini_get("session.name");
$session_id = $_COOKIE[$session_name];

// get the length of the request body
$length = (int) $_ENV['CONTENT_LENGTH'];

// read the POST data
$stdin = fopen("php://stdin", "rb");

while($chunk = fread($stdin, 4096)) {
    [...]
}

?>

解析 RFC1867 请求并非易事。我想,协调上传方和下载方也会相当棘手。

于 2012-10-16T15:32:49.460 回答
2

看来你不能直接。在文件完成上传之前,您的 PHP 脚本不会执行。使用 APC,您似乎可以获得上传文件的进度,但不能获得实际字节本身。唯一的另一种方法是在 PHP 中使用套接字编写您自己的服务器,等等。

作为替代方案,如果你有 Node.js(或者其他任何东西,真的),你可以这样做:

  1. 客户端 A 连接并开始上传
  2. 服务器开始将上传写入磁盘
  3. 客户端 B 连接,请求下载客户端 A 的数据
  4. 服务器从磁盘读取缓冲数据并发送给客户端 A
  5. 服务器在数据可用时继续发送,直到客户端 A 或 B 断开连接

磁盘缓冲区选项是最简单的,但对于大文件或实时流,如果客户端 B 能够跟上,或者如果数据丢失不没问题。

于 2012-10-16T14:41:24.187 回答
0

您应该研究 tus 协议 - 有一个支持它的 php 库 ( https://github.com/ankitpokhrel/tus-php ) 以及 Javascript 框架,包括客户端的 uppy (uppy.io)。

于 2019-05-23T22:08:29.390 回答