2013-02-27 49 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()。