[英]Process Uploaded file on web server without storing locally first?
我試圖在websever上實時處理用戶上傳的文件,但似乎,APACHE只在上傳完整文件后調用PHP。
當我使用CURL上傳文件,然后設置
轉移編碼:“Chunked”
我有一些成功,但不能通過瀏覽器做同樣的事情。
這個答案解釋了那里的問題。 無法設置Transfer-Encoding:“從瀏覽器中分塊”
在一個Nutshell問題中,當用戶將文件上傳到web服務器時,我希望webserver在第一個字節可用時立即開始處理它。 通過過程我的意思是,將它PIPING到命名管道。
不要先將500mb上傳到服務器,然后開始處理它。
但是使用當前的Webserver(APACHE-PHP),我似乎無法完成它。
有人可以解釋,使用什么技術堆棧或變通方法,以便我可以通過瀏覽器上傳大文件並開始處理它,只要第一個字節可用。
如果你真的想要那個(抱歉不認為這是一個好主意)你應該嘗試尋找一個能完成你工作的FUSE文件系統。
也許已經有一個https://github.com/libfuse/libfuse/wiki/Filesystems
或者你應該自己寫。
但請記住,一旦上傳完成並且后期腳本完成其工作,臨時文件將被刪除
你的意思是你想用PHP直播?
<?php
class VideoStream
{
private $path = "";
private $stream = "";
private $buffer = 102400;
private $start = -1;
private $end = -1;
private $size = 0;
function __construct($filePath)
{
$this->path = $filePath;
}
/**
* Open stream
*/
private function open()
{
if (!($this->stream = fopen($this->path, 'rb'))) {
die('Could not open stream for reading');
}
}
/**
* Set proper header to serve the video content
*/
private function setHeader()
{
ob_get_clean();
header("Content-Type: video/mp4");
header("Cache-Control: max-age=2592000, public");
header("Expires: ".gmdate('D, d M Y H:i:s', time()+2592000) . ' GMT');
header("Last-Modified: ".gmdate('D, d M Y H:i:s', @filemtime($this->path)) . ' GMT' );
$this->start = 0;
$this->size = filesize($this->path);
$this->end = $this->size - 1;
header("Accept-Ranges: 0-".$this->end);
if (isset($_SERVER['HTTP_RANGE'])) {
$c_start = $this->start;
$c_end = $this->end;
list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
if (strpos($range, ',') !== false) {
header('HTTP/1.1 416 Requested Range Not Satisfiable');
header("Content-Range: bytes $this->start-$this->end/$this->size");
exit;
}
if ($range == '-') {
$c_start = $this->size - substr($range, 1);
}else{
$range = explode('-', $range);
$c_start = $range[0];
$c_end = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $c_end;
}
$c_end = ($c_end > $this->end) ? $this->end : $c_end;
if ($c_start > $c_end || $c_start > $this->size - 1 || $c_end >= $this->size) {
header('HTTP/1.1 416 Requested Range Not Satisfiable');
header("Content-Range: bytes $this->start-$this->end/$this->size");
exit;
}
$this->start = $c_start;
$this->end = $c_end;
$length = $this->end - $this->start + 1;
fseek($this->stream, $this->start);
header('HTTP/1.1 206 Partial Content');
header("Content-Length: ".$length);
header("Content-Range: bytes $this->start-$this->end/".$this->size);
}
else
{
header("Content-Length: ".$this->size);
}
}
/**
* close curretly opened stream
*/
private function end()
{
fclose($this->stream);
exit;
}
/**
* perform the streaming of calculated range
*/
private function stream()
{
$i = $this->start;
set_time_limit(0);
while(!feof($this->stream) && $i <= $this->end) {
$bytesToRead = $this->buffer;
if(($i+$bytesToRead) > $this->end) {
$bytesToRead = $this->end - $i + 1;
}
$data = fread($this->stream, $bytesToRead);
echo $data;
flush();
$i += $bytesToRead;
}
}
/**
* Start streaming video content
*/
function start()
{
$this->open();
$this->setHeader();
$this->stream();
$this->end();
}
}
要使用此類,您必須編寫如下的簡單代碼:
$stream = new VideoStream($filePath);
$stream->start();
您可以使用html5可恢復上傳工具(如Resumable.js)上傳文件,並在收到后立即處理上傳的部分。
或者作為解決方法,您可以找到上傳文件的路徑(通常在/ tmp中),然后編寫后台作業以將其流式傳輸到第3個應用程序。 它可能更難。
可能還有其他解決方案......
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.