Download files from AWS S3 to client system - php

I am trying to provide download file option to my users. I am working on AWS EC2 with AWS PHP SDK V2.8. I am able to display images on my website. I try according to question force-download-with-php-on-amazon-s3 but no success. Most of the answer of this question are pretty old. I am using below code for uploading
try {
$result = $s3->putObject(array(
'Bucket' => $bucketName,
'ACL' => 'authenticated-read',
'Key' => "s3112.png",
'ServerSideEncryption' => 'AES256',
'SourceFile' => $filepath,
'ContentType' => mime_content_type($filepath),
'debug' => [
'logfn' => function ($msg) {
echo $msg . "\n";
},
'stream_size' => 0,
'scrub_auth' => true,
'http' => true,
],
));
} catch (S3Exception $e) {
echo $e->getMessage() . "\n";
}
Here is what is tried.
header('Content-disposition: attachment; filename=s3112.png');
header('Content-type: image/png');
readfile("https://s3-ap-southeast-1.amazonaws.com/mytest.sample/s3112.png");
//header("Location: https://s3-ap-southeast-1.amazonaws.com/mytest.sample/s3112.png");
//// Location redirection to a MP3 that lets the browser decide what to do.
//header("Location: https://s3-ap-southeast-1.amazonaws.com/mytest.sample/s3112.png");
I tried with
<a href="https://s3-ap-southeast-1.amazonaws.com/mytest.sample/s3112.png" download>
but no success. Any help appreciate.

If the object has public-read access, you should just be able to link to it.
You can also set read access to all objects in a bucket using a bucket policy.
You could also redirect to an S3 presigned URL of the object:
$cmd = $s3Client->getCommand('GetObject', [
'Bucket' => 'my-bucket',
'Key' => 'testKey'
]);
$request = $s3Client->createPresignedRequest($cmd, '+20 minutes');
// Get the actual presigned-url
$presignedUrl = (string) $request->getUri();
header('Location: ' . $presignedUrl);

Related

I Unable to move images in S3 bucket from our main server

I want to upload my images in the amazon s3 bucket. My images database uploaded to another web server. I am unable to move it to the S3 bucket. I referred to some solutions from StackOverflow.
Here is my code I have tried:
use \usr\share\php\AWSSDKforPHP\S3;
use \usr\share\php\AWSSDKforPHP\S3\S3Client;
use \usr\share\php\AWSSDKforPHP\S3\Exception\S3Exception;
$bucket = 'cdn.example.com';
$keyname = $newfilename;
$s3 = new S3Client([
'version' => 'latest',
'region' => 'us-east-1',
'credentials' => [
'key' => "**********************",
'secret' => "**********************************"
]
]);
try {
// Upload data.
$result = $s3->putObject([
'Bucket' => $bucket,
'Key' => $keyname,
'SourceFile' => $oldfilepath,
'ACL' => 'public-read'
]);
// Print the URL to the object.
echo $result['ObjectURL'] . PHP_EOL;
} catch (S3Exception $e) {
echo $e->getMessage() . PHP_EOL;
}
Showing error in output:
Fatal error: Class 'usr\share\php\AWSSDKforPHP\S3\S3Client' not found in /var/www/html/cron-jobs/shift-img.php on line 35

Uploading file to specific folder in s3 bucket, sdk php [duplicate]

This question already has answers here:
PutObject into directory Amazon s3 / PHP
(3 answers)
Closed 3 years ago.
I have this code below that should upload an image to my s3 bucket but I don't know how to tell it to upload to a specific folder (named videouploads) in my s3 bucket. Can anyone help?
require 'vendor/autoload.php';
use Aws\S3\S3Client;
// Instantiate an Amazon S3 client.
$s3 = new S3Client([
'version' => 'latest',
'region' => 'grabage',
'credentials' => [
'key' => 'garbage',
'secret' => 'grabage'
]
]);
$bucketName = 'cgrabage';
$file_Path = __DIR__ . '/my-image.png';
$key = basename($file_Path);
// Upload a publicly accessible file. The file size and type are determined by the SDK.
try {
$result = $s3->putObject([
'Bucket' => $bucketName,
'Key' => $key,
'Body' => fopen($file_Path, 'r'),
'ACL' => 'public-read',
]);
echo $result->get('ObjectURL');
} catch (Aws\S3\Exception\S3Exception $e) {
echo "There was an error uploading the file.\n";
echo $e->getMessage();
}
You need to put the directory information in the key.
$result = $s3->putObject([
'Bucket' => $bucketName,
'Key' => 'videouploads/' . $key,
'Body' => fopen($file_Path, 'r'),
'ACL' => 'public-read',
]);

Uploading to S3, how can I tell if it was a successful transfer?

Im uploading some images to S3, how can I check if it was a successful transfer?
Here is my code. I screw up the access key on purpose so the files do not upload, how can I catch this error and act upon it?
The code below does not catch anything, even though the images fail to upload.
$this->commands[] = $this->s3->getCommand('PutObject', [
'Bucket' => env('AWS_BUCKET'),
'Key' => $name,
'Body' => $img,
'ContentType' => $mime,
'ACL' => 'public-read'
]);
$pool = new CommandPool($this->s3, $this->commands);
$promise = $pool->promise();
try {
$result = $promise->wait();
}
catch (AwsException $e) {
var_dump($e)
}
Im using php sdk 3.0
I am also using PHP SDK 3.0 and was able to get the result of the upload using the following:
$result = $s3Client->putObject(array(
'Bucket' => $bucketName,
'Key' => $backupFileName,
'SourceFile' => $backupFile,
));
$code = $result['#metadata']['statusCode'];
$uri = $result['#metadata']['effectiveUri'];
if ($code === 200) {
// Success code here
}

Upload file on amazon S3 with PHP SDK

I'm trying to upload a picture on my amazon S3 via their PHP SDK. So I made a little script to do so. However, my script doesn't work and my exception doesn't send me back any error message.
I'm new with AWS thank you for your help.
Here is the code :
Config.php
<?php
return array(
'includes' => array('_aws'),
'services' => array(
'default_settings' => array(
'params' => array(
'key' => 'PUBLICKEY',
'secret' => 'PRIVATEKEY',
'region' => 'eu-west-1'
)
)
)
);
?>
Index.php
<?php
//Installing AWS SDK via phar
require 'aws.phar';
use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;
$bucket = 'infact';
$keyname = 'myImage';
// $filepath should be absolute path to a file on disk
$filepath = 'image.jpg';
// Instantiate the client.
$s3 = S3Client::factory('config.php');
// Upload a file.
try {
$result = $s3->putObject(array(
'Bucket' => $bucket,
'Key' => $keyname,
'SourceFile' => $filePath,
'ContentType' => 'text/plain',
'ACL' => 'public-read',
'StorageClass' => 'REDUCED_REDUNDANCY'
));
// Print the URL to the object.
echo $result['ObjectURL'] . "\n";
} catch (S3Exception $e) {
echo $e->getMessage() . "\n";
}
?>
EDIT : I'm now using this code but its still not working. I don't even have error or exception message.
<?php
require 'aws.phar';
use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;
$bucket = 'infactr';
$keyname = 'sample';
// $filepath should be absolute path to a file on disk
$filepath = 'image.jpg';
// Instantiate the client.
$s3 = S3Client::factory(array(
'key' => 'key',
'secret' => 'privatekey',
'region' => 'eu-west-1'
));
try {
// Upload data.
$result = $s3->putObject(array(
'Bucket' => $bucket,
'Key' => $keyname,
'SourceFile' => $filePath,
'ACL' => 'public-read',
'ContentType' => 'image/jpeg'
));
// Print the URL to the object.
echo $result['ObjectURL'] . "\n";
} catch (S3Exception $e) {
echo $e->getMessage() . "\n";
}
?>
Try something like this (from the AWS docs):
<?php
require 'aws.phar';
use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;
$bucket = '<your bucket name>';
$keyname = 'sample';
// $filepath should be absolute path to a file on disk
$filepath = '/path/to/image.jpg';
// Instantiate the client.
$s3 = S3Client::factory(array(
'key' => 'your AWS access key',
'secret' => 'your AWS secret access key'
));
try {
// Upload data.
$result = $s3->putObject(array(
'Bucket' => $bucket,
'Key' => $keyname,
'SourceFile' => $filepath,
'ACL' => 'public-read'
));
// Print the URL to the object.
echo $result['ObjectURL'] . "\n";
} catch (S3Exception $e) {
echo $e->getMessage() . "\n";
}
?>
It works fine for me as long as you have the right credentials. Keep in mind that the key name is the name of your file in S3 so if you want to have your key have the same name of your file you have to do something like: $keyname = 'image.jpg'; . Also, a jpg is generally not a plain/text file type, you can ommit that Content-type field or you can just simply specify: image/jpeg
$s3 = S3Client::factory('config.php');
should be
$s3 = S3Client::factory(include 'config.php');
For those looking an up to date working version, this is what I am using
// Instantiate the client.
$s3 = S3Client::factory(array(
'credentials' => [
'key' => $s3Key,
'secret' => $s3Secret,
],
'region' => 'us-west-2',
'version' => "2006-03-01"
));
try {
// Upload data.
$result = $s3->putObject(array(
'Bucket' => $s3Bucket,
'Key' => $fileId,
'SourceFile' => $filepath."/".$fileName
));
return $result['ObjectURL'];
} catch (S3Exception $e) {
return false;
}
An alternative way to explain is by showing the curl, and how to build it in php - the pragmatic approach.
Please don't stone me for ugly code, just thought that this example is easy to follow for uploading to Azure from PHP, or other language.
$azure1 ='https://viperprodstorage1.blob.core.windows.net/bucketnameAtAzure/';
$azure3 ='?sr=c&si=bucketnameAtAzure-policy&sig=GJ_verySecretHashFromAzure_aw%3D';
$shellCmd='ls -la '.$outFileName;
$lsOutput=shell_exec($shellCmd);
#print_r($lsOutput);
$exploded=explode(' ', $lsOutput);
#print_r($exploded);
$fileLength=$exploded[7];
$curlAzure1="curl -v -X PUT -T '" . $outFileName . "' -H 'Content-Length: " . $fileLength . "' ";
$buildedCurlForUploading=$curlAzure1."'".$azure1.$outFileName.$azure3."'";
var_dump($buildedCurlForUploading);
shell_exec($buildedCurlForUploading);
This is the actual curl
shell_exec("curl -v -X PUT -T 'fileName' -H 'Content-Length: fileSize' 'https://viperprodstorage1.blob.core.windows.net/bucketnameAtAzure/fileName?sr=c&si=bucketNameAtAzure-policy&sig=GJ_verySecretHashFromAzure_aw%3D'")
Below are the code for upload image/file in amazon s3 bucket.
function upload_agreement_data($target_path, $source_path, $file_name, $content_type)
{
$fileup_flag = false;
/*------------- call global settings helper function starts ----------------*/
$bucketName = "pilateslogic";
//$global_setting_option = '__cloud_front_bucket__';
//$bucketName = get_global_settings($global_setting_option);
/*------------- call global settings helper function ends ----------------*/
if(!$bucketName)
{
die("ERROR: Template bucket name not found!");
}
// Amazon profile_template template js upload URL
$target_profile_template_js_url = "/".$bucketName."/".$target_path;
// Chatching profile_template template js upload URL
//$source_profile_template_js_url = dirname(dirname(dirname(__FILE__))).$source_path."/".$file_name;
// file name
$template_js_file = $file_name;
$this->s3->setEndpoint("s3-ap-southeast-2.amazonaws.com");
if($this->s3->putObjectFile($source_path, $target_profile_template_js_url, $template_js_file, S3::ACL_PUBLIC_READ, array(), array("Content-Type" => $content_type)))
{
$fileup_flag = true;
}
return $fileup_flag;
}

phpqrcode + save cached file to Amazon instead of folder on server

What I do now is creating a QR code image (PNG) and save a copy of it in a folder on the root of my server. Now I would like to save this image not on my server but on my amazon bucket.
I know how I can save a file on amazon but I can't figure out how to make this work together.
This is my original code for saving it in a root folder on my server:
$fileName = $quiz_url . '.png';
$pngAbsoluteFilePath = APPLICATION_PATH . '/../public/qrcodecaches/' . $fileName;
$urlRelativeFilePath = '/qrcodecaches/' . $fileName;
// generating
if (!file_exists($pngAbsoluteFilePath)) {
QRcode::png('http://mysitelink.com/s/'.$quiz_url, $pngAbsoluteFilePath, 'L', 4, 2);
}
And this is how I save a file on Amazon:
$bucket = 'mybucket';
$map = 'qrcodecaches';
$client = S3Client::factory(array(
'key' => 'mykey',
'secret' => 'mysecret',
));
$fileName = $quiz_url . '.png';
$keyname = $map . '/' . $fileName;
try {
$client->putObject(array(
'Bucket' => $bucket,
'Key' => $keyname,
'Body' => fopen('/path/to/file', 'r'),
'ACL' => 'public-read',
));
} catch (S3Exception $e) {
echo "There was an error uploading the file.\n";
}
But what do I need to save in the 'Body' tag? Can somebody help me with this?
You can create the image file passing a temporary file name like this:
$pngAbsoluteFilePath = tempnam(sys_get_temp_dir(), 'qr_code_');
if (!file_exists($pngAbsoluteFilePath)) {
QRcode::png('http://mysitelink.com/s/'.$quiz_url, $pngAbsoluteFilePath, 'L', 4, 2);
}
then all you need to do is to get that file contents and pass it in to the Body of the object in bucket:
try {
$client->putObject(array(
'Bucket' => $bucket,
'Key' => $keyname,
'Body' => file_get_contents($pngAbsoluteFilePath), // like this
'ACL' => 'public-read'
));
}
catch (S3Exception $e) {
echo "There was an error uploading the file.\n";
}
After you're done - in case of successful upload - you can delete the temporary file. It is not necessary, however recommended because it will fill your /tmp with QR images until your server is restarted:
if ( empty($e) ) {
unlink($pngAbsoluteFilePath);
}
This worked well for me.
Amazon S3Client documentation suggests that you can poll to check that the upload was successful.
$client->waitUntilObjectExists(array(
'Bucket' => $bucket,
'Key' => $keyname
));
Alternatively if you're already writing the file to disk on your server you can supply S3Client with the path to that file and let it handle the filestream itself.
try {
$client->putObject(array(
'Bucket' => $bucket,
'Key' => $keyname,
'SourceFile' => '/path/to/file',
'ACL' => 'public-read'
));
} catch (S3Exception $e) {
echo "There was an error uploading the file.\n";
}
Source: http://docs.aws.amazon.com/aws-sdk-php/latest/class-Aws.S3.S3Client.html#_putObject

Categories