【问题标题】:How do I upload big (video) files in streams to AWS S3 with Laravel 5 and filesystem?如何使用 Laravel 5 和文件系统将流中的大(视频)文件上传到 AWS S3?
【发布时间】:2015-09-08 10:43:06
【问题描述】:

我想将一个大视频文件上传到我的 AWS S3 存储桶。经过好几个小时,我终于设法配置了我的 php.ininginx.conf 文件,所以它们允许更大的文件。

但后来我收到了"Fatal Error: Allowed Memory Size of XXXXXXXXXX Bytes Exhausted"。一段时间后,我发现更大的文件应该使用fopen()fwrite()fclose() 与流一起上传。

由于我使用的是 Laravel 5,因此文件系统会处理大部分内容。除了我无法让它工作。

我当前的ResourceController@store 看起来像这样:

public function store(ResourceRequest $request)
{
    /* Prepare data */
    $resource = new Resource();
    $key = 'resource-'.$resource->id;
    $bucket = env('AWS_BUCKET');
    $filePath = $request->file('resource')->getRealPath();

    /* Open & write stream */
    $stream = fopen($filePath, 'w');
    Storage::writeStream($key, $stream, ['public']);

    /* Store entry in DB */
    $resource->title = $request->title;
    $resource->save();

    /* Success message */
    session()->flash('message', $request->title . ' uploadet!');
    return redirect()->route('resource-index');
}

但是现在我得到了这个很长的错误:

SignatureV4.php 第 148 行中的CouldNotCreateChecksumException:

无法为提供的上传正文计算 sha256 校验和,因为它不可搜索。为防止出现此错误,您可以 1) 在请求中包含 ContentMD5 或 ContentSHA256 参数,2) 为正文使用可搜索流,或 3) 将不可搜索流包装在 GuzzleHttp\Stream\CachingStream 对象中。不过,您应该小心并记住 CachingStream 使用 PHP 临时流。这意味着流将被临时存储在本地磁盘上。

所以我现在完全迷路了。我什至不知道我是否走在正确的轨道上。以下是我试图理解的资源:

更让我困惑的是,除了流之外,似乎还有另一种上传大文件的方法:所谓的"multipart" upload。我实际上认为这就是溪流的全部意义所在......

有什么区别?

【问题讨论】:

    标签: php amazon-web-services file-upload amazon-s3 laravel-5


    【解决方案1】:

    我遇到了同样的问题并想出了这个解决方案。 而不是使用

    Storage::put('file.jpg', $contents);
    

    这当然遇到了“内存不足错误”我使用了这种方法:

    use Aws\S3\MultipartUploader;
    use Aws\Exception\MultipartUploadException;
    
    // ...
    
    public function uploadToS3($fromPath, $toPath)
    {
        $disk = Storage::disk('s3');
        $uploader = new MultipartUploader($disk->getDriver()->getAdapter()->getClient(), $fromPath, [
            'bucket' => Config::get('filesystems.disks.s3.bucket'),
            'key'    => $toPath,
        ]);
    
        try {
            $result = $uploader->upload();
            echo "Upload complete";
        } catch (MultipartUploadException $e) {
            echo $e->getMessage();
        }
    }
    

    用 Laravel 5.1 测试

    以下是官方 AWS PHP SDK 文档: http://docs.aws.amazon.com/aws-sdk-php/v3/guide/service/s3-multipart-upload.html

    【讨论】:

    • 嗨 HazA,你能帮帮我吗?如何添加 MultipartUploader 类以在像 UploadController 这样的 Contoller 上使用?,谢谢!
    【解决方案2】:

    流式传输部分适用于下载。

    对于上传,您需要知道内容大小。对于大文件,分段上传是可行的方法。

    【讨论】:

    • 到目前为止,您在澄清我应该关注的内容方面获得了支持。如果你能提供一个工作代码示例,我也会给你打勾。如果在我自己弄清楚之前没有给出更好的答案,无论如何你都会得到复选标记。感谢您的宝贵时间!
    • AWS Multipart-upload 完美运行!但是上传阻止了页面很长时间,所以我想我现在要去学习 ajax 了......干杯!
    猜你喜欢
    • 2018-09-30
    • 2019-10-26
    • 2016-03-14
    • 2019-01-08
    • 1970-01-01
    • 1970-01-01
    • 2016-04-07
    • 2018-07-07
    • 2021-05-14
    相关资源
    最近更新 更多