You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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编码的字符串,必须先解码成原始二进制数据再上传:

  1. 获取Base64编码的内容字符串
  2. 用base64_decode()解码为原始二进制内容
  3. 将解码后的二进制数据作为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 11:56:27