tinu
tinu

Reputation: 558

PHP file-streaming from client over the server to client

Question

Is it possible to stream an uploading file over PHP, so that an other client can download it while the first one is uploading?

I don't want to save the file permanently on the server. How can I do that?

Why PHP?

The downloading client shouldn't need an additional software to get the stream. I thought the easiest way would be the webbrowser.

Upvotes: 3

Views: 2311

Answers (3)

larowlan
larowlan

Reputation: 101

You should look into the tus protocol - there is a php library to support it (https://github.com/ankitpokhrel/tus-php) as well as Javascript frameworks including uppy (uppy.io) for client-side.

Upvotes: 0

cleong
cleong

Reputation: 7646

It's possible, but the implementation is going to be rather awkward. The main obstacle is that the handling of multipart POST request is hardcoded into PHP. It will always save the files to temporary locations before invoking your script. One workaround is to set up PHP-CLI as a CGI script. As the CLI version of PHP is not HTTP-aware, it lets you get your hands on the incoming data.

The .CGI file will look something like this:

#!/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)) {
    [...]
}

?>

Parsing the RFC1867 request is non-trivial. Coordinating the uploading party with the downloading party will also be rather tricky, I imagine.

Upvotes: 3

Brad
Brad

Reputation: 163602

It appears that you can't directly. Your PHP script won't execute until the file is finished uploading. Using APC, it seems you can get the progress of a file being uploaded, but not the actual bytes itself. The only other way would be to write your own server in PHP with sockets and what not.

As an alternative, if you had Node.js (or just about anything else, really), you could do something like this:

  1. Client A connects and begins upload
  2. Server begins writing upload to disk
  3. Client B connects, requests download of Client A's data
  4. Server reads buffered data from disk and sends to Client A
  5. Server continues sending as data is available, until Client A or B disconnect

The disk buffer option is the easiest, but for large files or live streams, you may want to roll over to sending directly as the data comes in without disk in the middle, if Client B is able to keep up, or if data loss isn't a problem.

Upvotes: 2

Related Questions