【问题标题】:Can't upload image to S3 bucket using direct url of image无法使用图像的直接 url 将图像上传到 S3 存储桶
【发布时间】:2017-12-08 03:09:13
【问题描述】:

这是我的代码,适用于表单上传(通过 $_FILES)(我省略了那部分代码,因为它无关紧要):

$file = "http://i.imgur.com/QLQjDpT.jpg";

$s3 = S3Client::factory(array(
    'region' => $region,
    'version' => $version
));  

        try {

            $content_type = "image/" . $ext;

            $to_send = array();

            $to_send["SourceFile"] = $file;

            $to_send["Bucket"] = $bucket;
            $to_send["Key"] = $file_path;
            $to_send["ACL"] = 'public-read';
            $to_send["ContentType"] = $content_type;

            // Upload a file.
            $result = $s3->putObject($to_send);

正如我所说,如果文件是 $_FILES["files"]["tmp_name"],则此方法有效,但如果 $file 是带有未捕获异常“Aws\Exception\CouldNotCreateChecksumException”且消息为 'A sha256 checksum could not be calculated for the provided upload body, because it was not seekable. To prevent this error you can either 1) include the ContentMD5 or ContentSHA256 parameters with your request, 2) use a seekable stream for the body, or 3) wrap the non-seekable stream in a GuzzleHttp\Psr7\CachingStream object. You should be careful though and remember that the CachingStream utilizes PHP temp streams. This means that the stream will be temporarily stored on the local disk.' 的有效图像 url,则会失败。有谁知道为什么会这样?可能有什么问题? Tyvm 为您提供帮助!

【问题讨论】:

    标签: php amazon-web-services amazon-s3


    【解决方案1】:

    对于寻找选项#3 (CachingStream) 的任何人,您可以将PutObject 命令传递给Body 流而不是源文件。

    use GuzzleHttp\Psr7\Stream;
    use GuzzleHttp\Psr7\CachingStream;
    ...
    $s3->putObject([
        'Bucket'        => $bucket,
        'Key'           => $file_path,
        'Body'          => new CachingStream(
            new Stream(fopen($file, 'r'))
        ),
        'ACL'           => 'public-read',
        'ContentType'   => $content_type,
    ]);
    

    或者,您可以使用 guzzle 请求文件。

    $client = new GuzzleHttp\Client();
    $response = $client->get($file);
    
    $s3->putObject([
        'Bucket'        => $bucket,
        'Key'           => $file_path,
        'Body'          => $response->getBody(),
        'ACL'           => 'public-read',
        'ContentType'   => $content_type,
    ]);
    

    【讨论】:

    • 非常感谢 Kyro - 效果很好(第一名)!任何阅读 htis 的人 - 确保您正确设置了 $content_type。我正在使用 image/jpg(更多测试代码)上传测试 PDF,但它没有工作...... application/pdf 工作得很好!
    【解决方案2】:

    您必须将文件下载到首先运行 PHP 的服务器。 S3 上传仅适用于本地文件 - 这就是 $_FILES["files"]["tmp_name"] 起作用的原因 - 它是 PHP 服务器的本地文件。

    【讨论】:

    • 您正在使用字符串填充$to_send["SourceFile"]。您想要file_put_contents(file_get_contents($url),'/tmp/tmpfile'); $to_send["SourceFile"] = '/tmp/tmpfile'; 之类的东西 - 基本上先下载文件然后发送该文件。
    • 选项#3,CachingStream 怎么样?我想使用它,但似乎无法使用它。
    猜你喜欢
    • 2020-02-14
    • 2019-06-14
    • 2021-07-20
    • 1970-01-01
    • 2017-02-01
    • 2020-12-30
    • 2018-03-11
    • 2016-04-24
    • 1970-01-01
    相关资源
    最近更新 更多