如何将Outlook附件实际内容而非字节数据上传至Amazon S3?
问题:将Outlook邮件附件保存至Amazon S3时,文件内容显示为字节数据而非实际内容
我用aws-php-sdk把Outlook邮件附件上传到Amazon S3,上传成功了,但下载打开后只显示内容字节数据。不知道怎么通过contentBytes存储文件的实际内容。
试过用$attachment->getContentBytes()->getContents(),结果上传的是0KB文件;用$attachment->getContentBytes()的话,打开文件会显示内容字节数据。
<FileAttachment>来自msgraph-sdk-php,用来获取Outlook邮件附件。
当前代码:
private function saveToS3(string $s3_directory, \Microsoft\Graph\Model\FileAttachment $attachment) { $aws_s3_key = 'XXXXXXX'; $aws_s3_secret = 'XXXXXXXX'; $aws_s3_region = 'us-west-1'; $aws_bucket = 'test-storage'; $s3Client = new S3Client([ 'version' => 'latest', 'region' => $aws_s3_region, 'credentials' => [ 'key' => $aws_s3_key, 'secret' => $aws_s3_secret, ], ]); return $s3Client->putObject([ 'Bucket' => $aws_bucket, 'Key' => $s3_directory, 'Body' => $attachment->getContentBytes(), 'ContentType' => $attachment->getContentType(), ]); }
示例FileAttachment数据:
{ "@odata.type": "#microsoft.graph.fileAttachment", "@odata.mediaContentType": "application/octet-stream", "id": "AAMkAGQyMzYyNXXXXXXXXXXXXXXXxLjl14fH8FdpE=", "lastModifiedDateTime": "2023-07-31T22:43:52Z", "name": "README.md", "contentType": "application/octet-stream", "size": 1708, "isInline": false, "contentId": "f_leudosmi0", "contentLocation": null, "contentBytes": "IyBDUk0gaW5XXXXXXXXXXXXXXXXXXXXXgZnJhbWV3b3JrIAo=" }
请问怎么上传文件实际内容而非内容字节数据到Amazon S3?
解决方案
问题核心是contentBytes返回的是Base64编码的字符串,必须先解码成原始二进制数据再上传:
- 获取Base64编码的内容字符串
- 用
base64_decode()解码为原始二进制内容 - 将解码后的二进制数据作为
Body参数传入S3的putObject方法
修改后的代码:
private function saveToS3(string $s3_directory, \Microsoft\Graph\Model\FileAttachment $attachment) { $aws_s3_key = 'XXXXXXX'; $aws_s3_secret = 'XXXXXXXX'; $aws_s3_region = 'us-west-1'; $aws_bucket = 'test-storage'; $s3Client = new S3Client([ 'version' => 'latest', 'region' => $aws_s3_region, 'credentials' => [ 'key' => $aws_s3_key, 'secret' => $aws_s3_secret, ], ]); // 解码Base64编码的内容字节 $decodedContent = base64_decode($attachment->getContentBytes()); return $s3Client->putObject([ 'Bucket' => $aws_bucket, 'Key' => $s3_directory, 'Body' => $decodedContent, 'ContentType' => $attachment->getContentType(), ]); }
之前方法失效的原因:
- 直接上传
$attachment->getContentBytes(),本质是把Base64编码的字符串原封不动传到S3,下载后自然显示编码后的文本 - 调用
$attachment->getContentBytes()->getContents()得到0KB文件,是因为getContentBytes()返回的是字符串而非流对象,字符串没有getContents()方法,实际执行会返回空值或报错
内容的提问来源于stack exchange,提问作者MalcolmInTheCenter
相关产品推荐
相关产品推荐

