Amazon S3 设置元数据使用 AWS SDK PHP v2 upload() 失败

Posted

技术标签:

【中文标题】Amazon S3 设置元数据使用 AWS SDK PHP v2 upload() 失败【英文标题】:Amazon S3 setting metadata fails using AWS SDK PHP v2 upload() 【发布时间】:2013-09-25 08:15:57 【问题描述】:

在使用 AWS 开发工具包 php v2 将文件上传到 Amazon S3 时,我在设置“元数据”选项时遇到问题。 upload() 方法的 documentation that I'm reading 声明第 5 个参数是一个选项数组...

*$options 执行命令时使用的自定义选项: - 参数:自定义 与上传一起使用的参数。 参数必须映射到 PutObject 或 InitiateMultipartUpload 操作参数。 - min_part_size:允许每个上传部分的最小大小 执行分段上传。 - 并发:最大数量 并发分段上传。 - before_upload:回调调用 在每次分段上传之前。回调将收到一个 带有上下文的 Guzzle\Common\Event 对象。*

我的upload() 代码如下所示..

$upload = $client->upload(
  '<BUCKETNAME>',
  'metadatatest.upload.jpg',
  fopen('metadatatest.jpg','r'),
  'public-read',
  array('Metadata' => array(
    'SomeKeyString' => 'SomeValueString'
  ))
);

...上传后没有设置元数据。

如果我使用putObject()as documented here,我认为与upload()相比,这是一种“较低级别”的方法...

$putObject = $client->putObject(
  array(
    'Bucket' => '<BUCKETNAME>',
    'Key' => 'metadatatest.putobject.jpg',
    'Body' => file_get_contents('metadatatest.jpg'),
    'ACL' => 'public-read',
    'Metadata' => array(
      'SomeKeyString' => 'SomeValueString'
    )
  )
);

当我调用getObject()或使用putObject()上传时直接在浏览器中查看文件时,元数据成功返回

$getObject = $client->getObject(
  array(
    'Bucket' => '<BUCKETNAME>',
    'Key' => 'metadatatest.putobject.jpg'
  )
);

我更喜欢使用 $client-&gt;upload() 方法作为文档说明

将文件、流或字符串上传到存储桶。如果上传大小超过指定阈值,将使用 并行分段上传。

我不确定我错过了什么?

【问题讨论】:

这似乎是一个错误。请在github.com/aws/aws-sdk-php/issues 报告。我还要提到您正在上传的对象的大小,因为这可能只是分段上传的问题。 @JeremyLindblom 干杯我会试一试这条大道,文件很小,putObject() 处理得很好。 @JeremyLindblom 这不是真正的代码错误,而是该方法的文档编写方式的问题。在查看实际源代码之前,我还发现它令人困惑。也许你们可以通过一些可以澄清事情的例子来改进它。 @dcro 啊,我明白这有多令人困惑。注意! 【参考方案1】:

如果您不进行分段上传,使用upload()putObject() 确实没有区别。你可以看看AWS PHP SDK source code 但基本上upload 方法只是像这样调用putObject

// Perform a simple PutObject operation
return $this->putObject(array(
    'Bucket' => $bucket,
    'Key'    => $key,
    'Body'   => $body,
    'ACL'    => $acl
) + $options['params']);

这在 SDK 文档中不是很清楚,但是您需要将最后一个参数作为带有键 params 的数组发送,其值是带有 Metadata 键和值的第二个数组,如下所示:

$upload = $client->upload(
    '<BUCKETNAME>',
    'metadatatest.upload.jpg',
    fopen('metadatatest.jpg','r'),
    'public-read',
    array('params' => array(
        'Metadata' => array(
            'SomeKeyString' => 'SomeValueString'
    )))
);

但是,我可以使用 putObject 调用来实现相同的目的。

【讨论】:

太棒了,这很好地解释了@dcro,我实际上最终改用UploadBuilder::newInstance(),这确实有助于提高清晰度。 实际上...我只是查看了您链接到的源代码,当它在if ($body-&gt;getSize() &lt; $options['min_part_size']) 的约束范围内时,它将调用putObject(),否则它将执行UploadBuilder::newInstance 调用,因此使用您对params 数组的说明我现在可以安全地使用upload() 方法了。 没错。如果不为min_part_size 指定值,则默认值为5MB。

以上是关于Amazon S3 设置元数据使用 AWS SDK PHP v2 upload() 失败的主要内容,如果未能解决你的问题,请参考以下文章

golang Amazon S3使用AWS SDK for Go选择CSV示例

golang Amazon S3使用AWS SDK for Go选择带有JSON的示例

在iOS Swift中不使用AWS SDK在Amazon S3存储桶中上传的背景图像(背景模式)

使用 AWS SDK for PHP 上传的 Amazon S3 文件总是“application/octet-stream”?

如何使用 Java SDK 将目录与 AWS S3 同步?

Javascript || AWS S3 SDK &croppie 文件上传错误