2017-07-08 60 views
1

我試圖直接從php://input流中解壓zip文件。我跑Laravel家園,PHP 7.1.3-3+deb.sury.org~xenial+1,與myproject.app/upload端點,這裏是curl命令:解壓縮或膨脹php://輸入流?

curl --request POST \ 
    --url 'http://myproject.app/upload' \ 
    --data-binary "@myfile.zip" \ 

這是所有我試過的方法列表,其中所有的失敗:


dd(file_get_contents('compress.zlib://php://input')); 

file_get_contents()函數:不能代表類型輸入的流作爲文件描述


$fh = fopen('php://input', 'rb'); 

stream_filter_append($fh, 'zlib.inflate', STREAM_FILTER_READ, array('window'=>15)); 

$data = ''; 

while (!feof($fh)) { 
    $data .= fread($fh, 8192); 
} 

dd($data); 

「」


$zip = new ZipArchive; 

$zip->open('php://input'); 
$zip->extractTo(storage_path() . '/' . 'myfile'); 
$zip->close(); 

ZipArchive :: extractTo():無效的或者未初始化的對象郵編

這裏是所有我對找到的鏈接subject:

http://php.net/manual/en/wrappers.php#83220

http://php.net/manual/en/wrappers.php#109657

http://php.net/manual/en/wrappers.compression.php#118461

https://secure.phabricator.com/rP42566379dc3c4fd01a73067215da4a7ca18f9c17

https://arjunphp.com/how-to-unpack-a-zip-file-using-php/

我開始認爲這是不可能與PHP的內置的ZIP功能流進行操作。編寫臨時文件的開銷和複雜性會非常令人失望。有誰知道如何做到這一點,或者它是一個錯誤?

回答

1

經過更多的研究,我發現了答案,但並不令人滿意。由於現代世界的巨大失誤之一,gzip和zip格式不同。 gzip編碼單個文件(這就是我們經常看到tar.gz的原因),而zip則編碼文件和文件夾。我試圖上傳一個zip文件,並用gzip解碼,但這不起作用。更多信息:

https://stackoverflow.com/a/20765054/539149

https://stackoverflow.com/a/1579506/539149

這個問題的另一部分是,PHP忽略了gzip的提供流過濾器:

https://stackoverflow.com/a/11926679/539149

因此,即使gzopen('php://temp', 'rb')作品,gzopen('php://input', 'rb')因爲輸入流不可回捲。這使得無法在內存流中操作,因爲無法將數據寫入流,然後在單獨的gzip連接上讀取解壓縮數據。這意味着下面的代碼工作:

$input = fopen("php://input", "rb"); 
$temp = fopen("php://temp", "rb+"); 
stream_copy_to_stream($input, $temp); 
rewind($temp); 
dd(stream_get_contents(gzopen('php://temp', 'rb'))); 

人們已經嘗試各種解決辦法,但他們都做到位擺弄:

http://php.net/manual/en/function.gzopen.php#105676

http://php.net/manual/en/function.gzdecode.php#112200

我還是設法得到一個純粹的內存解決方案工作,但由於它不可能使用流,一個不必要的副本發生:

// works (stream + string) 
dd(gzdecode(file_get_contents('php://input'))); 

// works (stream + file) 
dd(stream_get_contents(gzopen(storage_path() . '/' . 'myfile.gz', 'rb'))); 

// works (stream + file) 
dd(file_get_contents('compress.zlib://' . storage_path() . '/' . 'myfile.gz')); 

// doesn't work (stream) 
dd(stream_get_contents(gzopen('php://input', 'rb'))); 

// doesn't work (stream + filter) 
dd(file_get_contents('compress.zlib://php://input')); 

如果沒有可用的例子,我必須假設PHP的ZIP實現是不完整的,因爲它不能在流操作。如果有人有更多的信息,我很樂意再次訪問。請發佈任何通過流實現壓縮上傳/下載的示例或存儲庫,謝謝!