如何使用AWS SDK for PHP实现S3存储桶之间的文件直接复制
AWS SDK for PHP实现S3跨桶直接复制方案
Ruby SDK提供的
copy_to/copy_from是对S3原生CopyObjectAPI的语法糖封装,AWS SDK for PHP没有提供对应的同名方法,直接调用底层API即可实现相同的跨桶直接复制效果,不需要将文件下载到本地中转。
前置前提
- 确保你的AWS身份凭证对源桶有
s3:GetObject权限,对目标桶有s3:PutObject权限 - 如果两个桶属于不同AWS账户,需要额外配置跨桶访问权限
- 小于5GB的文件可以直接用单请求复制,大于5GB需要用分块复制
SDK v3 实现代码(当前主流版本)
<?php require 'vendor/autoload.php'; use Aws\S3\S3Client; use Aws\Exception\AwsException; // 初始化S3客户端 $s3Client = new S3Client([ 'version' => 'latest', 'region' => 'us-east-1', // 替换为你的桶对应区域 // 凭证如果在环境变量/EC2 IAM角色/本地配置文件中可省略显式配置 // 'credentials' => [ // 'key' => '你的AccessKey', // 'secret' => '你的SecretKey', // ] ]); $sourceBucket = '源桶名称'; $sourceKey = '源文件路径/文件名.后缀'; $destBucket = '目标桶名称'; $destKey = '目标文件路径/文件名.后缀'; try { $result = $s3Client->copyObject([ 'Bucket' => $destBucket, 'Key' => $destKey, 'CopySource' => "{$sourceBucket}/{$sourceKey}", // 可选配置:自定义目标文件ACL,默认继承源文件元数据 // 'ACL' => 'public-read', // 'MetadataDirective' => 'REPLACE', // 需要修改元数据时添加此参数 ]); echo "文件复制成功,目标文件ETag:" . $result['ETag']; } catch (AwsException $e) { echo "复制出错:" . $e->getMessage(); }
大于5GB大文件分块复制实现
单请求复制最大支持5GB文件,超过大小限制可使用SDK内置的自动分块复制能力:
<?php // 初始化S3客户端代码同上 $sourceBucket = '源桶名称'; $sourceKey = '源大文件路径'; $destBucket = '目标桶名称'; $destKey = '目标大文件路径'; // 注册S3流包装器,直接读取源桶文件流 $s3Client->registerStreamWrapper(); try { // upload方法会自动判断文件大小,超过阈值自动分块复制 $result = $s3Client->upload( $destBucket, $destKey, fopen("s3://{$sourceBucket}/{$sourceKey}", 'r'), 'private' // 目标文件ACL ); echo "大文件复制成功,ETag:" . $result['ETag']; } catch (AwsException $e) { echo "大文件复制出错:" . $e->getMessage(); }
注意事项
- 跨区域复制也可使用上述方法,仅需要S3客户端的区域与目标桶区域一致即可,AWS底层自动处理跨区域传输
- 源文件开启服务端加密时不需要额外处理,复制会默认继承加密配置,也可通过参数自定义目标文件加密规则
- 所有复制操作均在S3服务端完成,不会消耗本地服务器带宽
内容的提问来源于stack exchange,提问作者MilanG
相关产品推荐
相关产品推荐

