PHP 将远程图像保存到 Amazon S3

Posted

技术标签:

【中文标题】PHP 将远程图像保存到 Amazon S3【英文标题】:PHP save remote image to Amazon S3 【发布时间】:2011-12-20 18:01:40 【问题描述】:

有没有办法使用 URL 抓取图像并将其直接保存到亚马逊?

使用 php

我的另一个选择是在本地保存文件并使用 S3 PHP 类发送。

【问题讨论】:

【参考方案1】:

当您“抓取图像”时,您至少必须将其写入本地临时文件。这是因为无论您使用 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。”

【讨论】:

这是我最终选择的路径。下载然后将临时文件上传到亚马逊。谢谢!【参考方案2】:

您可以使用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');

它还允许您使用内置 PHP 函数存储和检索 Amazon S3 中的数据,例如 file_get_contentsfopencopyrenameunlinkmkdirrmdir、等等

【讨论】:

这对我不起作用。它在第一个参数中需要一个 s3:// url。【参考方案3】:

当然,您可以将图像上传到您的服务器,然后将其传输到 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

【讨论】:

谢谢!好主意,但唯一的问题是我无法进行任何处理,例如将文件名保存到数据库并在将文件传递给 Amazon 之前重命名文件。所以我不得不走另一条路。 @Scott 您可以使用 选项设置自定义文件名。以及如何在 DB 中保存文件名 - 可以通过在表单提交时使用 JS 向您的服务器发送单独的 AJAX 请求来完成。无论如何,它应该比上传和传输整个文件便宜,你同意吗?

以上是关于PHP 将远程图像保存到 Amazon S3的主要内容,如果未能解决你的问题,请参考以下文章

使用 Axios 进行 Amazon S3 远程文件上传

Amazon S3 .NET:上传 base64 图像数据?

将 base64 字符串保存到 Amazon S3

如何在不下载文件的情况下搜索amazon S3存储桶中的文件内容

如何使用 PHP 显示来自 Amazon S3 的图像?

PHP 获取远程图像,调整大小并保存