【问题标题】:Upload file created with fopen to AWS S3 bucket将使用 fopen 创建的文件上传到 AWS S3 存储桶
【发布时间】:2020-02-07 21:42:36
【问题描述】:

我有一些 PHP 代码用于循环数据库查询并创建 CSV 文件。 该文件使用fopen() 创建并在例程结束时下载。没问题。 但是,在 CSV 创建结束时,我尝试使用相同的生成内容 ($output) 将文件推送到 S3 存储桶。

失败并显示以下消息:

AWS 错误类型:服务器,AWS 错误消息:您提供的标头暗示未实现的功能,用户代理:aws-sdk-php2/2.7.27 Guzzle/3.9.3 curl/7.47.0 PHP/7.0.33-0ubuntu0.16.04.9 在 /www/MIND/gen6portal/vendor/aws/aws-sdk-php/src/Aws/Common/Exception/NamespaceExceptionFactory.php 第 91 行抛出 p>

我知道这与我尝试将流作为 S3 密钥的主体传递有关,但我不知道该怎么做。任何指针表示赞赏。 代码如下:

$output = fopen('php://output', 'w');
while ($rows = mysqli_fetch_assoc($result)) {
    fputcsv($output, $rows); // there's some more processing that I do but this works fine
}

//Now I want to upload it to S3: 

$s3->putObject([
    'Bucket' => 'mybucket',
    'Key' => 'myfile.csv',
    'Body' => $output,
    'ACL' => 'public-read'
]);

fclose($output);

有趣的是,如果我只是尝试获取一个现有文件(以验证我是否可以访问该 S3 存储桶)它上传就好了:

s3->putObject([
    'Bucket' => 'mybucket',
    'Key' => "myfile.csv",
    'Body' => fopen('temp.csv', 'rb'),
    'ACL' => 'public-read'
            ]);

【问题讨论】:

  • 有什么原因你不能把它放到一个临时文件中,然后将该临时文件上传到 S3?

标签: php amazon-s3 fopen


【解决方案1】:

由于per the docsphp://output 是只写流,因此您无法再次读取它。

但是,您可以使用临时流,如下所示:

$output = fopen('php://memory', 'w+');
while ($rows = mysqli_fetch_assoc($result)) {
    fputcsv($output, $rows);
}
rewind($output);

$s3->putObject([
    'Bucket' => 'mybucket',
    'Key' => 'myfile.csv',
    'Body' => stream_get_contents($output),
    'ACL' => 'public-read'
]);

fclose($output);

免责声明:我还没有对此进行测试,如果您遇到更多麻烦,请大声疾呼。

P.S.:请注意,我将句柄的模式更改为 w+ 以使其也可读。

【讨论】:

  • 谢谢。我尝试了临时文件方法,但遇到了“拒绝访问”问题:致命错误:未捕获 Aws\S3\Exception\AccessDeniedException:AWS 错误代码:AccessDenied,状态代码:403,AWS 请求 ID:07AA8C5530D16350,AWS 错误类型:客户端,AWS 错误消息:访问被拒绝,用户代理:aws-sdk-php2/2.7.27 Guzzle/3.9.3 curl/7.47.0 PHP/7.0.33-0ubuntu0.16.04.9 抛出 /www/MIND /gen6portal/vendor/aws/aws-sdk-php/src/Aws/Common/Exception/NamespaceExceptionFactory.php 第 91 行
  • 我知道我对该存储桶有写访问权限,如果我尝试通过 PHP 从服务器上传现有文件,它可以正常工作。
  • 这与使用内存流有什么关系?
  • 那么您是使用内存流还是临时文件尝试呢?内存根本不应该有任何权限问题,因为它发生在 PHP 进程中。
  • 我尝试使用临时文件和内存流并得到相同的访问被拒绝错误。就像 S3 不喜欢我要上传的内容一样。但我 100% 确定我拥有正确的权限。
【解决方案2】:

在尝试将文件发送到 S3 之前,您似乎应该 fclose() 文件。如果文件写入仍处于打开状态,则该文件仍在使用中且不可用。

【讨论】:

    猜你喜欢
    • 2018-04-25
    • 2021-02-07
    • 1970-01-01
    • 2015-09-10
    • 2020-03-17
    • 2012-09-08
    • 2018-11-12
    • 2017-10-17
    • 2017-11-10
    相关资源
    最近更新 更多