2012-06-28 51 views
1

我正在編寫一個使用php來包裝網站功能並在json \ xml中返回所有內容的API。我一直在使用捲曲,到目前爲止效果很好。 該網站有一個標準的文件上傳帖子,接受文件高達1GB。PHP重定向文件發佈流

所以問題是如何將文件上傳流重定向到通訊網站?

我可以下載文件,然後上傳它,但我的服務器僅限於20MG。這似乎是一個糟糕的解決方案。

它甚至可以控制流並將其直接重定向到網站?

回答

2

我preserverd底部爲後人原始,但事實證明,是有辦法做到這一點

你需要使用什麼是HTTP PUT方法的組合(這不幸的是,不以原生瀏覽器形式提供),PHP php://input包裝器和流式PHP Socket。這會產生一些限制 - PHP不允許php://input用於發佈數據,但它對於PUT filedata沒有任何幫助 - 聰明!

如果你打算用apache來嘗試這個,你將需要安裝一個激活的mod_actions。您還需要在虛擬主機/ .htaccess中指定PUT腳本和Script指令。

http://blog.haraldkraft.de/2009/08/invalid-command-script-in-apache-configuration/

這使得put方法只對一個URL端點。這是打開套接字並將數據轉發到別處的文件。在我的示例下面,這只是index.php

我已經準備了使用python requests模塊作爲發送放置請求與圖像文件的客戶端的樣板示例。如果您運行remote_server.py它將打開一個服務,只監聽端口並等待來自php的轉發消息。 put.py將實際放入請求發送給PHP。根據您的設置,您需要將主機put.pyindex.php設置爲您在虛擬主機中定義的主機。

運行put.py將打開包含的圖像文件,將其發送到您的PHP虛擬主機,它將打開一個套接字並將接收到的數據流式傳輸到python僞服務並將其打印到終端中的stdout。流式PHP轉發器!

沒有什麼能夠阻止你使用任何遠程服務,在另一種語言中以同樣的方式監聽TCP端口。客戶端可以用相同的方式重寫,只要它可以發送PUT請求即可。

完整的例子是在這裏:

https://github.com/DeaconDesperado/php-streamer

其實我有很多的樂趣與這個問題。請讓我知道它是如何工作的,我們可以將它修補到一起。

開始原來的答案

PHP中沒有原生的方法,可以異步傳遞一個文件,因爲它與請求主體進來,而無需關閉保存其狀態到光盤上以某種方式。這意味着你很難受到服務器內存限制(20MB)的限制。在其上接收該請求後的$_FILES超全局初始化的方式取決於此,因爲它會嘗試在multipart數據遷移到tmp目錄。

類似的東西可以使用套接字來實現,因爲它至少會繞過HTTP協議,但如果文件在HTTP請求中傳遞,php仍然會嘗試在它之前將其有狀態地保存在內存中用它做任何事情。如果沒有切實可行的辦法,你就會設置這個過程的最後一步。

有一個Stream庫接近,但仍然依賴於在服務器端讀取內存不足 - 它必須在那裏是

你所描述的是一點點的HTTP協議之外,特別是因爲請求體太大了。 HTTP是基於請求/響應的機制,一個依賴於另一個......在中間點完成就地流式上傳非常困難,因爲這意味着某些協議會上傳,而這些協議會在

有人可能會認爲這比HTTP更受限於HTTP,並且由於PHP是根據HTTP協議設計的,因此您正在其舒適區之外移動。

像這樣的部署經常會嘗試使用其他腳本語言取得高成功(例如,Python中的Twisted,很多人在NodeJS中使用其併發設計模式,在Ruby或Java中還有其他選擇,約。)

+0

好吧,但我有點限於PHP。使用流,可以使用php://輸入嗎?資料來源:http://php.net/manual/en/wrappers.php.php – LuisFonseca

+0

其實,你可能已經得到了我;)。 'php:// temp'看起來很有前途,如果它允許在超全局初始化之前執行邏輯。可以將它與'exec()'結合起來使之成爲可能。我現在要做一個概念驗證。 – DeaconDesperado

+0

'php:// input'不可用於''multipart/form-data'的enctype。也許'臨時'是? – DeaconDesperado