我使用Laravel将多个文件上传到S3存储桶但无法在客户端正确获取进度数据。
在客户端,我有以下(简化):
var xhr = new XMLHttpRequest();
xhr.addEventListener("progress", updateProgress, false);
xhr.addEventListener("load", transferComplete, false);
xhr.open("POST", "my_url_to_upload");
xhr.send(formData);//formData is defined earlier and contains multiple files
function updateProgress(e) {
console.log('updateProgress', e);
}
function transferComplete(e) {
console.log("Files uploaded successfully.", e);
}
在Laravel的一面:
$files = \Input::file('file');
$s3 = \Storage::disk('s3');
foreach ($files as $file)
{
$file_name = "/some_folder/" . $file->getClientOriginalName();
$s3->put($file_name, file_get_contents($file), 'public');
}
就将文件上传到S3存储桶而言,这非常有用。
问题在于,当上传多个文件时,客户端updateProgress
功能只会被调用一次,并且仅在所有文件上传后(而不是在每个文件之后和上传期间)。
理想情况下,进度条会在文件上传期间定期更新,因此在上传大文件时,它会显示接近实时的进度(而不仅仅是每个文件的完成时间)。
在上传过程中,我如何让Laravel(或一般的PHP)报告进度?
答案 0 :(得分:1)
以下是如何在SDK v3中执行此操作:
$client = new S3Client(/* config */);
$result = $client->putObject([
'Bucket' => 'bucket-name',
'Key' => 'bucket-name/file.ext',
'SourceFile' => 'local-file.ext',
'ContentType' => 'application/pdf',
'@http' => [
'progress' => function ($downloadTotalSize, $downloadSizeSoFar, $uploadTotalSize, $uploadSizeSoFar) {
printf(
"%s of %s downloaded, %s of %s uploaded.\n",
$downloadSizeSoFar,
$downloadTotalSize,
$uploadSizeSoFar,
$uploadTotalSize
);
}
]
]);
AWS文档中解释了这一点 - S3 Config section。它的工作原理是暴露GuzzleHttp的progress
属性可调用,如this SO answer中所述。
我理解你的做法有点不同(使用Streams),但我确信你可以根据自己的需要调整我的示例。