php - 使用 AWS S3 createMultipartUpload (AWS PHP SDK v3) 上传进度统计信息
问题描述
问题
目前我正在使用 AWS S3 createMultipartUpload 函数将大文件(视频)上传到 AWS S3 存储。这就像一个魅力。
但是,由于将视频上传到 AWS S3 存储需要大量的上传时间,我正在尝试找到一种解决方案来检索上传进度统计信息,例如,uploadBytes 和 totalBytesToUpload 来计算视频上传完成之前的剩余时间完全的。
我在互联网上搜索了数十个 StackOverflow 问题和博客,了解如何实时检索上传文件的这些统计信息,但还没有找到可行的解决方案。
我尝试了什么?
原始代码
$result = $this->s3Client->createMultipartUpload([
'Bucket' => $this->bucket,
'Key' => $path,
'StorageClass' => 'STANDARD',
'ACL' => 'public-read',
'Metadata' => $metaDataValues
]);
使用 @http 进度 (GuzzleHttp) 的代码(在https://stackoverflow.com/a/43700547/4686900上找到)
$result = $this->s3Client->createMultipartUpload([
'Bucket' => $this->bucket,
'Key' => $path,
'StorageClass' => 'STANDARD',
'ACL' => 'public-read',
'Metadata' => $metaDataValues,
'@http' => [
'progress' => function ($downloadTotalSize, $downloadSizeSoFar, $uploadTotalSize, $uploadSizeSoFar) {
$this->loggerService->logError("down [" . $downloadSizeSoFar ."]/[".$downloadTotalSize."] up [".$uploadSizeSoFar."]/[".$uploadTotalSize."]");
}
]
]);
此代码在将视频上传到 AWS S3 存储后记录以下输出
[2020-09-29 16:29:45] customLog.ERROR: down [0]/[0] up [0]/[0] [] []
[2020-09-29 16:29:45] customLog.ERROR: down [0]/[0] up [0]/[0] [] []
[2020-09-29 16:29:45] customLog.ERROR: down [0]/[0] up [0]/[0] [] []
[2020-09-29 16:29:45] customLog.ERROR: down [0]/[0] up [0]/[0] [] []
[2020-09-29 16:29:45] customLog.ERROR: down [0]/[0] up [0]/[0] [] []
[2020-09-29 16:29:45] customLog.ERROR: down [0]/[0] up [0]/[0] [] []
[2020-09-29 16:29:45] customLog.ERROR: down [0]/[0] up [0]/[0] [] []
[2020-09-29 16:29:45] customLog.ERROR: down [0]/[0] up [0]/[0] [] []
[2020-09-29 16:29:45] customLog.ERROR: down [0]/[0] up [0]/[0] [] []
[2020-09-29 16:29:45] customLog.ERROR: down [435]/[0] up [0]/[0] [] []
[2020-09-29 16:29:45] customLog.ERROR: down [435]/[0] up [0]/[0] [] []
[2020-09-29 16:29:45] customLog.ERROR: down [435]/[0] up [0]/[0] [] []
[2020-09-29 16:29:45] customLog.ERROR: down [435]/[0] up [0]/[0] [] []
[2020-09-29 16:29:45] customLog.ERROR: down [435]/[0] up [0]/[0] [] []
[2020-09-29 16:29:45] customLog.ERROR: down [435]/[0] up [0]/[0] [] []
在日志中,您会看到统计信息 [0]/[0],因此没有任何变化。
我试图考虑其他解决方案,例如使用 JavaScript AJAX XHR 函数计算上传字节数,请参阅代码:
$.ajax(
{
//...
xhr: function() {
let xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
let percentComplete = (evt.loaded / evt.total) * 100;
console.log(percentComplete)
}
}, false);
return xhr;
}
// ...
});
但是,此代码仅捕获我在本地和我们自己的服务器之间传输的字节数,而不是在我的本地环境和 AWS S3 存储服务器之间传输的字节数。
完整代码
public function uploadMultipart($file, $path, $metaDataValues = [])
{
ini_set('max_execution_time', 0);
$parts = array();
$result = $this->s3Client->createMultipartUpload([
'Bucket' => $this->bucket,
'Key' => $path,
'StorageClass' => 'STANDARD',
'ACL' => 'public-read',
'Metadata' => $metaDataValues,
'@http' => [
'progress' => function ($downloadTotalSize, $downloadSizeSoFar, $uploadTotalSize, $uploadSizeSoFar) {
$this->loggerService->logError("down [" . $downloadSizeSoFar ."]/[".$downloadTotalSize."] up [".$uploadSizeSoFar."]/[".$uploadTotalSize."]");
}
]
]);
$uploadId = $result['UploadId'];
// Upload the file in parts.
try
{
$file = fopen($file, 'r');
$partNumber = 1;
while (!feof($file))
{
$result = $this->s3Client->uploadPart([
'Bucket' => $this->bucket,
'Key' => $path,
'UploadId' => $uploadId,
'PartNumber' => $partNumber,
'Body' => fread($file, 500 * 1024 * 1024),
]);
$parts['Parts'][$partNumber] = [
'PartNumber' => $partNumber,
'ETag' => $result['ETag'],
];
$partNumber++;
}
fclose($file);
}
catch (S3Exception $e) {
$this->s3Client->abortMultipartUpload([
'Bucket' => $this->bucket,
'Key' => $path,
'UploadId' => $uploadId
]);
$this->logger->error("Error multipart uploading: " . $e->getMessage() . " on " . $e->getLine() . " for " . $e->getFile());
}
// Complete the multipart upload.
$result = $this->s3Client->completeMultipartUpload([
'Bucket' => $this->bucket,
'Key' => $path,
'UploadId' => $uploadId,
'MultipartUpload' => $parts,
]);
return $result['Location'];
}
问题
如何在本地系统和 AWS S3 存储服务器之间使用 S3 createMultipartUpload 函数或替代方式检索上传的字节数和要上传的总字节数。
ps 我正在使用 PHP 7.2.20、Symfony 3.4 和 AWS SDK for PHP v3
解决方案
推荐阅读
- python - 如果给定的键和值从字典列表中匹配,则获取所有字典
- python - 在 jupyter notebook 中并排显示图像
- reactjs - 向 AspNet Core 3.0-preview React 项目添加授权(带身份验证)
- sql-server - 仅当行与当前值不同时才更新/插入行
- html - 将本地副本上传到 bluehost 时,我的网页的相对文件路径需要更改
- sql - Mutating table error when trying to Insert into Table with select
- r - R Shiny 数据表组行以提高可读性
- elasticsearch - 弹性搜索:如何在文档中划分一个数字然后排序?
- kubernetes - MinIO AWS CLI 通过 nginx-ingress 控制器
- android - 编译后房间持久性问题