You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 操作S3时10GB大文件move/copy功能失效问题

Laravel S3存储大文件move/copy操作失败的解决方法

问题原因

AWS S3对单步copyObject操作的文件大小限制为5GB,而Laravel的Storage facade默认的move/copy方法仅调用了常规的S3复制接口,没有处理超过5GB的大文件分块复制场景,因此10GB的文件操作会直接失败,且可能仅返回false而不抛出异常。

解决方案

直接使用AWS SDK的MultipartCopy类实现分块复制,再结合删除源文件完成move操作。以下是修改后的代码:

try {
    // 获取S3客户端实例
    $s3Client = Storage::disk('s3')->getClient();
    $bucket = config('filesystems.disks.s3.bucket');
    
    $sourceKey = $param['source'];
    $targetKey = $param['target'];

    // 获取源文件的大小信息
    $sourceMeta = $s3Client->headObject([
        'Bucket' => $bucket,
        'Key' => $sourceKey,
    ]);
    $fileSize = $sourceMeta['ContentLength'];

    // 初始化分块复制,设置每块大小为100MB(可根据服务器内存调整)
    $multipartCopy = new \Aws\S3\MultipartCopy($s3Client, [
        'Bucket' => $bucket,
        'Key' => $targetKey,
        'CopySource' => "{$bucket}/{$sourceKey}",
    ], [
        'part_size' => 100 * 1024 * 1024,
    ]);

    // 执行分块复制
    $copyResult = $multipartCopy->copy();

    // 复制成功后删除源文件(move操作的核心逻辑)
    if ($copyResult['@metadata']['statusCode'] === 200) {
        $s3Client->deleteObject([
            'Bucket' => $bucket,
            'Key' => $sourceKey,
        ]);
        dd(true);
    } else {
        dd(false);
    }
} catch (\Exception $e) {
    return [
        "status" => 0,
        "msg" => $e->getMessage(),
    ];
}

额外注意事项

  1. 权限检查:确保你的IAM用户拥有s3:PutObject、s3:GetObject、s3:DeleteObject以及s3:ListBucket权限,分块操作需要这些权限支持。
  2. 超时设置:大文件复制耗时较长,需在config/filesystems.php的S3配置中增加超时参数:
's3' => [
    // 原有配置...
    'http' => [
        'timeout' => 3600, // 设置1小时超时
        'connect_timeout' => 60,
    ],
],
  1. SDK版本:确保你的AWS SDK版本支持MultipartCopy类,Laravel 8+默认依赖的AWS SDK版本已包含该功能,若版本过低需执行composer update aws/aws-sdk-php更新。

内容的提问来源于stack exchange,提问作者Lokesh Mukeriya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 13:35:17