如何使用 Laravel 5 和文件系统将流中的大(视频)文件上传到 AWS S3?

How do I upload big (video) files in streams to AWS S3 with Laravel 5 and filesystem?

我想将一个大视频文件上传到我的 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');
}

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

CouldNotCreateChecksumException in SignatureV4.php line 148:

A sha256 checksum could not be calculated for the provided upload body, because it was not seekable. To prevent this error you can either 1) include the ContentMD5 or ContentSHA256 parameters with your request, 2) use a seekable stream for the body, or 3) wrap the non-seekable stream in a GuzzleHttp\Stream\CachingStream object. You should be careful though and remember that the CachingStream utilizes PHP temp streams. This means that the stream will be temporarily stored on the local disk.

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

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

有什么区别?

流媒体部分适用于下载。

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

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

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

其中当然运行变成了"out of memory error"我用的是这个方法:

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