Reputation: 860
I have some PHP code that I use to loop through a database query and create a CSV file.
The file is created with fopen()
and downloaded at the end of the routine. No problem with that.
However, at the end of the CSV creation I try to push a file to an S3 bucket using that same generated content ($output
).
It fails with the following message:
AWS Error Type: server, AWS Error Message: A header you provided implies functionality that is not implemented, User-Agent: aws-sdk-php2/2.7.27 Guzzle/3.9.3 curl/7.47.0 PHP/7.0.33-0ubuntu0.16.04.9 thrown in /www/MIND/gen6portal/vendor/aws/aws-sdk-php/src/Aws/Common/Exception/NamespaceExceptionFactory.php on line 91
I know it has to do with me trying to pass the stream as the body of the S3 key but I don't know how else to do this. Any pointers are appreciated. Here's the code:
$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);
Interesting enough, if I simply try to get an existing file (to validate that I have access to that S3 bucket) it uploads just fine:
s3->putObject([
'Bucket' => 'mybucket',
'Key' => "myfile.csv",
'Body' => fopen('temp.csv', 'rb'),
'ACL' => 'public-read'
]);
Upvotes: 2
Views: 4390
Reputation: 53
It seems like you should fclose() the file before you try to send it to S3. If the file writing is still open the file is still in use and unavailable.
Upvotes: 0
Reputation: 5248
As per the docs the stream php://output
is a write-only stream, therefore you can not read from it again.
However, you could use a temp stream, like so:
$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);
Disclaimer: I did not test that yet, shout if you run into further trouble.
P.S.: Note I changed the mode for the handle to w+
in order to have it readable too.
Upvotes: 3