将远程图片保存到Amazon S3的PHP方法

6
有没有一种用URL抓取图像并直接保存到亚马逊的方法?
可以使用PHP完成吗?
我的另一个选择是将文件保存在本地,然后使用S3 PHP类发送它。
3个回答

6
当你"获取图像"时,你至少需要将其写入本地临时文件。这是因为无论你使用fopen()还是curl来访问文件,你都需要一种方式将流写入Amazon。我不确定是否有一种编程流可以直接连接远程文件到S3。实际上,从理论上讲,这是不可能的,因为S3不能执行脚本,图像也无法运行脚本。
如果你想要最小化存储在内存中的信息量,你可以通过某种形式的流缓冲加载图像,但写入临时文件应该是最简单的方法。如果你因为系统中有太多用户而用尽了空间,你可以升级到一个更大的服务器或在负载均衡器下添加另一个服务器。我个人在我的系统上使用Amazon的S3 PHP类,并使用像这样的脚本将其从本地临时文件直接移动到S3:
function upload_image( $image_data )
{
    //
    // Write the image to S3
    //  
    $s3 = new AmazonS3();
    $bucket = ACTIVITY_S3_BUCKET;
    $image_id = uniqid('myscript');
    $path = ACTIVITY_S3_FOLDER.'/'.$image_id;
    $response = $s3->create_object($bucket, $path, array(
        'body'  => $image_data,
        'acl'   =>  AmazonS3::ACL_PUBLIC
    ));
    $image_url = 'https://s3.amazonaws.com/'.ACTIVITY_S3_BUCKET.'/'.$path;
    return $image_id;
}

显然,这不是一个强大的脚本,但我想分享下我的经历。 我应该补充一点,因为在这种情况下您似乎最关心的是处理能力,请查看这篇有趣的帖子,在云中调整大小数十亿个图像。http://www.nslms.com/2010/11/01/how-to-resize-billions-of-images-in-the-cloud/

更新 根据这个答案How best to resize images off-server,“PHP / GD让您直接在HTTP响应中发送jpeg。”


这是我最终选择的路径。下载并上传临时文件到亚马逊。谢谢! - Scott Yu - builds stuff

3

使用Amazon S3 Stream Wrapper,您可以直接将远程文件保存到S3中。无需在服务器上保存临时副本。

// Register the stream wrapper from an S3Client object
$client->registerStreamWrapper();

// Copy a remote file to Amazon S3
copy('http://example.com/1.jpg', 's3://bucket/key');

Amazon S3提供了内置的PHP函数,如file_get_contentsfopencopyrenameunlinkmkdirrmdir等,方便您存储和检索数据。


这对我不起作用。它期望在第一个参数中使用s3:// url。 - Andy

0
当然,您可以将图像上传到您的服务器,然后将其转移到Amazon S3服务。但是,我认为,让客户能够直接使用表单将图像上传到S3会更好:
<form action="https://s3-bucket.s3.amazonaws.com/" method="post" enctype="multipart/form-data">
    <input type="hidden" name="key" value="uploads/${filename}">
    <input type="hidden" name="AWSAccessKeyId" value="YOUR_AWS_ACCESS_KEY"> 
    <input type="hidden" name="acl" value="private"> 
    <input type="hidden" name="success_action_redirect" value="http://localhost/">
    <input type="hidden" name="policy" value="YOUR_POLICY_DOCUMENT_BASE64_ENCODED">
    <input type="hidden" name="signature" value="YOUR_CALCULATED_SIGNATURE">
    <input type="hidden" name="Content-Type" value="image/jpeg">
    File to upload to S3: 
    <input name="file" type="file"> 
    <br> 
    <input type="submit" value="Upload File to S3"> 
</form> 

您可以在官方文档中找到详细信息: http://aws.amazon.com/articles/1434


谢谢!很棒的想法,但唯一的问题是我无法进行任何处理,比如将文件名保存到数据库并在传递给亚马逊之前重命名文件。所以我不得不选择另一条路。 - Scott Yu - builds stuff
@Scott,您可以使用<input type="hidden" name="key" />选项设置自定义文件名。那么将文件名保存在数据库中呢?可以通过在表单提交时使用JS向服务器发送单独的AJAX请求来完成。这应该比上传和传输整个文件更便宜,您同意吗? - RReverser

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接