2013-02-27 72 views
2

我試圖上傳很多圖像到S3存儲桶。考慮到速度,我希望通過將數據保存在內存中來減少磁盤讀取和寫入的次數。爲此,我想出了以下方案:傳遞二進制數據到S3 PutObject

//fetch binary image data from remote URL 
$contents = file_get_contents("http://somesite.com/image.jpg"); 
//trim the image as per: http://stackoverflow.com/a/15104071/568884 
$out = shell_exec('echo ' . base64_encode($contents) . " | base64 -d | convert - -fuzz 10% -trim jpeg:-"); 
//create a temporary resource to pass to S3's inputResource() method. 
$resource = fopen('php://temp', 'r+'); 
//write the binary data into the empty resource. 
fwrite($resource, $out); 
//pass the resource and length of binary data into inputResource() 
$ir = $this->s3->inputResource($resource, strlen($out)); 
//finally transfer the resource from machine to S3. 
$this->s3->putObject($ir, $bucket, $s3_path, S3::ACL_PUBLIC_READ); 

的錯誤是:S3 :: putObject():將requestTimeout]你的套接字連接到服務器是無法讀取或內寫入超時期限。空閒連接將被關閉並且數據不會寫入S3。

如果我將$ out的賦值替換爲簡單的空字符串:$out = "";然後,庫按預期方式成功地將0字節文件寫入S3。

我正在使用CodeIgniter S3庫...這只是AWS S3 API afaik的一個包裝。

+0

PHP是不是真的這個東西的最佳選擇。一個更好的設計會使用諸如Python,Java或Ruby之類的批處理工作排隊。您可以輕鬆地從您的PHP應用程序創建工作,並讓工作人員處理繁重的工作。 – jamieb 2013-03-04 02:06:35

+0

你使用s3 SDK還是第三方課程? – 2013-03-09 00:27:00

+0

按照問題「我正在使用CodeIgniter S3庫,它只是AWS S3 API afaik的包裝器。」 – 2013-03-09 02:25:20

回答

1

您正在將文件句柄$resource傳遞給庫,但是,您先將其寫入庫中,以便文件指針位於文件末尾。

該庫可能無法處理該邊緣案例(它的源代碼表明)。

在寫入文件之前但在將文件傳遞到S3庫之前,您可以嘗試使用rewind($resource)文件。

如果你想加快一點點,你可以讓PHP使用較小文件的內存,如果你想通過切換php://tempphp://memory。有關詳細信息和選項,請參閱the php:// wrapper docs

S3庫btw。不是官方的。如果您啓用通知和警告,您可能會看到一些報告的問題,因爲它仍包含PHP 4代碼。

+0

賓果。 '倒帶'做到了!對延遲表示歉意。我早已放棄了這種嘗試(其他問題優先),現在只是重構它。很棒。謝謝! – 2013-05-13 10:52:39

0

RequestTimeout錯誤的可能來源可能是您對putObject的調用指定了與正在發送的實際數據不同的內容長度。每一個亞馬遜代表the AWS forums

一個你可能引發的requestTimeout錯誤方法是發送一個PUT 請求指定2的內容長度,但包括在請求體中只有1對象數據的字節 。在等待20秒後剩餘字節到達 後,Amazon S3將以RequestTimeour 錯誤進行響應。

因此,當您使用strlen()函數時,您的臨時文件可能報告了錯誤的長度,並且此錯誤值導致S3以異常作出響應。

據有關php documentation for strlen()意見,功能,因爲它假定字符串可以在一個文件中報告了錯誤的字節數總是ASCII:

如果是這樣,可能把二進制數據作爲unocode串的情況下和 返回錯誤值

嘗試使用到mb_strlen()一個電話,這應該總是報告正確的字節數更換的strlen()。