我有一个PHP脚本,它使用copyObject操作将文件从一个文件夹复制到S3存储桶中的另一个文件夹.但是,如果文件名包含百分号(%),则会导致400错误请求错误:

<Error><Code>InvalidArgument</Code><Message>Invalid copy source encoding</Message><ArgumentName>x-amz-copy-source</Argum (truncated...) InvalidArgument (client): Invalid copy source encoding - <Error><Code>InvalidArgument</Code><Message>Invalid copy source encoding</Message><ArgumentName>x-amz-copy-source</ArgumentName><ArgumentValue>x-amz-copy-source</ArgumentValue><RequestId>MJ6JPP4CJY87A4D2</RequestId><HostId>3iEO5xRKnpHhNAp+pTpGYUWgVEwP97k2qtQuJRTIiBKRL9KFGTMJLXUu8irha4PTtW2q3hWdxQA=</HostId></Error>'

有问题的文件名的一个例子是:id!@GB$%.jpg

相关的PHP代码:-

$filename = 'ID!@£$%.png';
$file_key = 'source/' . $filename;
$new_file_key = 'destination/' . $filename;
$bucketname = 'my-bucket';

$result = $client->copyObject(array(
  'Bucket'     => $bucketname,
  'Key'        => $new_file_key,
  'CopySource' => $bucketname."/".($file_key),
  'MetadataDirective' => 'COPY',
));

我还try 使用AWS CLI执行复制对象操作,它对以下文件名运行良好:

aws s3api copy-object --copy-source my-bucket/source/ID!@£$%.png --key destination/ID!@£$%.jpg --bucket my-bucket

有没有人能帮我找出我做错了什么?

谢谢.

推荐答案

当您在S3中使用AWS SDK for PHP将对象从一个位置复制到另一个位置时,源(CopySource)必须以特定方式进行URL编码.您在文件名中遇到的特殊字符(如%)问题是由于URL编码要求造成的.

以下是您需要做的:

  1. URL-encode the filename: 使用PHPrawurlencode()函数对文件密钥进行编码.这个函数是专门为编码查询字符串值而设计的,比urlencode()更适合这项任务.

  2. Avoid double encoding: 由于您已经在使用URL编码,因此请确保AWS SDK for PHP不会再次try 对该值进行编码.

让我们修改您的代码:

$filename = 'ID!@£$%.png';
$file_key = 'source/' . $filename;
$new_file_key = 'destination/' . $filename;
$bucketname = 'my-bucket';

// URL encode the file key for the copy source
$encoded_file_key = 'source/' . rawurlencode($filename);

$result = $client->copyObject(array(
  'Bucket'     => $bucketname,
  'Key'        => $new_file_key,
  'CopySource' => $bucketname . "/" . $encoded_file_key,
  'MetadataDirective' => 'COPY',
));

通过对值为CopySource的文件键进行URL编码,您的代码应该可以对包含特殊字符的文件名起到预期的作用.

Php相关问答推荐

模型中的Laravel自定义查询字段

Symfony/Panther Web抓取不适用于登录后的内容(云功能)

在ShipStation for WooCommerce中使用自定义订单项目元数据

msgraph-sdk-php v2如何传递skiptoken到request?

在Google云存储对象上从PHP设置缓存控制TTL会更改错误的元数据

创建一个新的可变产品及其属性以用于WooCommerce中的变体

将数组推送到数组时,数组推送()出现问题

WordPress插件和JSON不是有效的响应错误

返回WooCommerce中的所有已启用变体

移动应用:在PHP中忽略Cookie?

带Redhat php curl的http_code 0

从字符串转换日期和/或时间时,Laravel转换失败

登录后重定向在WooCommerce中购买产品的用户

获取作者';在WordPress中使用PHP

在具有Angular 的 Laravel 应用程序中,不显示图像

标签打印机的 CSS

向元素添加类时添加循环错误

根据WooCommerce中的产品重量更改简单产品的输入数量步值

php var_dump(1) 返回字符串(4)

如何在 WooCommerce 中显示每个自定义选项卡的内容