将使用fopen创建的文件上传到AWS S3存储桶

时间:2020-02-07 21:42:36

标签: php amazon-s3 fopen

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

它失败,并显示以下消息:

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

我知道这与尝试将流作为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'
            ]);

2 个答案:

答案 0 :(得分: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+,以使其也可读。

答案 1 :(得分:0)

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