AWS S3 URL is different from the original one - php

I am uploading files from php to aws s3. I have successfully uploaded the file.
The url it is returning is => https://BUCKETNAME.s3.ap-south-1.amazonaws.com/images1740/1550830121572.jpg
The actual url is => https://s3.ap-south-1.amazonaws.com/BUCKETNAME/images1740/1550830121572.jpg
(bucket name is coming in starting instead at the end of url)
Because of this it is giving me error while loading images => "Specified Key not found"
$source = $source;
$bucket = 'xxxxxxxxxxxxxxxxx';
$keyname = 'images'.$usr_id."/".$name;
// for push
$s3 = S3Client::factory(
array(
'credentials' => array(
'key' => "xxxxxxxxxxxxxx",
'secret' => "xxxxxxxxxxxxxxx"
),
'version' => 'latest',
'region' => 'ap-south-1'
)
);
try {
// Upload data.
$result = $s3->putObject(array(
'Bucket' => $bucket,
'Key' => $keyname,
'SourceFile' => $source,
'ServerSideEncryption' => 'AES256',
));
// Print the URL to the object.
print_r($result);
return $result['ObjectURL'] . PHP_EOL;
// print_r($result);
} catch (S3Exception $e) {
echo $e->getMessage() . PHP_EOL;
}

Set use_path_style_endpoint to true when initializing the S3 client to have it use the S3 path style endpoint by default when building the object URL. 1
Implementation details has the object URL to be in the path style if the bucket name makes a valid domain name otherwise it fallback to the S3 path style.
You want to keep the later behavior all the time.
$s3 = S3Client::factory(
array(
'credentials' => array(
'key' => "xxxxxxxxxxxxxx",
'secret' => "xxxxxxxxxxxxxxx"
),
'use_path_style_endpoint' => true,
'version' => 'latest',
'region' => 'ap-south-1'
)
);
You can also do as below if you wanted to disable it one-time for the PutObject operation.
$result = $s3->putObject(array(
'Bucket' => $bucket,
'Key' => $keyname,
'SourceFile' => $source,
'ServerSideEncryption' => 'AES256',
'#use_path_style_endpoint' => true
));

Related

Delete object (single image) in Amazon S3 using php Yii2 not working?

Here I have the code of connection
$s3 = S3Client::factory(array(
'key' => 'xxxxxxxxx',
'secret' => '0xxxxxxxxxx',
'version' => 'latest',
'region' => 'us-west-2',
))
Here the bucket name $bucket = 'ariana-ios-storages'; and here the name of file $p = parse_url($images->name) which is the
name of file in amazon to delete;
Here is the code to delete the file
$delete = $s3->deleteObject([
'Bucket' => $bucket,
'Key' => $p['path']
]);
var_dump($delete);
exit();
The file path is generated like this;
It is not deleting the single file from the bucket so can any one help what i am missing
public function actionDeleteImages($id)
{
$exportImage= \common\models\ExportImages::findOne($id);
$base_url='base url to bucket';
$s3 = S3Client::factory(array(
'key' => 'xxxxxxx',
'secret' => '0pdfOx21xxxxxxxxxx',
'version' => 'latest',
'region' => 'us-west-2',
));
$bucket = 'name of bucket';
$key=urldecode(explode($base_url,$exportImage->name)[1]);// $images->name is Path from Db, base url is path to s3 server
$delete = $s3->deleteObject([
'Bucket' => 'ariana-ios-storages',
'Key' => $key
]);
$object_exist = $s3->doesObjectExist($bucket,$key);
if(!$object_exist){
return "succesfully deleted";
}else{
return "there is some problem while procesing the deletion";
}
}
}

Delete a file from s3 bucket

I've created an upload and download service in php-symfony2. This is working fine. Now I want to delete the uploaded file. Any Example?
Note: No data storing to database tables.
Deleting One Object (Non-Versioned Bucket)
Create instance of S3 client using Aws\S3\S3Client class factory().
$s3 = S3Client::factory();
Execute the Aws\S3\S3Client::deleteObject() method with bucket name and a key name.
$result = $s3->deleteObject(array(
'Bucket' => $bucket,
'Key' => $keyname
));
If versioning is enabled DELETE MARKER Will be added. (References)
EXAMPLE
<?php
require 'vendor/autoload.php';
use Aws\S3\S3Client;
$s3 = S3Client::factory();
$bucket = '*** Your Bucket Name ***';
$keyname = '*** Your Object Key ***';
$result = $s3->deleteObject(array(
'Bucket' => $bucket,
'Key' => $keyname
));
More References can be found here.
You can use deleteObject() method, refer the doc.
use Aws\S3\S3Client;
$s3 = S3Client::factory();
$bucket = '*** Your Bucket Name ***';
$keyname = '*** Your Object Key ***';
$result = $s3->deleteObject(array(
'Bucket' => $bucket,
'Key' => $keyname
));
After lot of solution i tried i found the solution that works for me perfectly.
$s3 = Storage::disk('s3');
$s3->delete('filename');
You can use the aws s3 delete API method which delete the uploaded file. you can achieve it like below.
use Aws\S3\S3Client;
$s3 = new S3(awsAccessKey, awsSecretKey);
$s3->deleteObject("bucketname", filename);
This Code Worked For me.
$s3Client = new S3Client([
'version' => 'latest',
'region' => 'your region',
'credentials' => [
'key' => '**AWS ACCESS KEY**',
'secret' => '**AWS SECRET ACCESS KEY**',
],
]);
try {
$result = $s3Client->deleteObject(array(
'Bucket' => '**YOUR BUCKET**',
'Key' => "videos/file.mp4"
));
return 1;
} catch (S3Exception $e) {
return $e->getMessage() . PHP_EOL;
}
Unfortunately, Arsalan's answer doesn't appear to work anymore. What worked for me, using access and secret keys was:
$this->s3 = new S3Client([
'driver' => 's3',
'version' => 'latest',
'region' => env('AWS_DEFAULT_REGION'),
'credentials' => [
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY')
]
]);
$this->s3->putObject([
'Bucket' => env('AWS_BUCKET'),
'Key' => env('AWS_SECRET_ACCESS_KEY'),
'Body' => $body,
'Key' => $key
]);

Cant connect to AWS s3, using aws-php-sdk. Invalid Request

My error message:
Uncaught Aws\S3\Exception\InvalidRequestException:
AWS Error Code: InvalidRequest,
Status Code: 400, AWS Request ID: xxx,
AWS Error Type: client,
AWS Error Message: The authorization mechanism you have provided is not supported.
Please use AWS4-HMAC-SHA256., User-Agent: aws-sdk-php2/2.7.27 Guzzle/3.9.3 curl/7.47.0 PHP/7.0.15-0ubuntu0.16.04.4
My Code:
<?php
use Aws\S3\S3Client;
require 'vendor/autoload.php';
$config = array(
'key' => 'xxx',
'secret' => 'xxx',
'bucket' => 'myBucket'
);
$filepath = '/var/www/html/aws3/test.txt';
//s3
// Instantiate the client.
$s3 = S3Client::factory();
// Upload a file.
$result = $s3->putObject(array(
'Bucket' => $config['bucket'],
'Key' => $config['key'],
'SourceFile' => $filepath,
'Endpoint' => 's3-eu-central-1.amazonaws.com',
'Signature'=> 'v4',
'Region' => 'eu-central-1',
//'ContentType' => 'text/plain',
//'ACL' => 'public-read',
//'StorageClass' => 'REDUCED_REDUNDANCY',
//'Metadata' => array(
// 'param1' => 'value 1',
// 'param2' => 'value 2'
)
);
echo $result['ObjectURL'];
Cant figure out why I cant get through. I have the right parameters in my call. My code is mostly copied from their aws-sdk-php example page. So it shouldnt be to much fault there.
I am using aws cli and have set upp my configure and credentials file under ~/.aws/
EDIT:
Got it to work! This is my code now:
<?php
// Get dependencies
use Aws\S3\S3Client;
require 'vendor/autoload.php';
// File to upload
$filepath = '/var/www/html/aws3/test.txt';
// instantiate the Client
$s3Client = S3Client::factory(array(
'credentials' => array(
'key' => 'AKIAJVKBYTTADILGRTVQ',
'secret' => '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'
),
'region' => 'eu-central-1',
'version' => 'latest',
'signature_version' => 'v4'
));
// Upload a file.
$result = $s3Client->putObject(array(
'Bucket' => "myBucket",//some filebucket name
'Key' => "some_file_name.txt",//name of the object with which it is created on s3
'SourceFile' => $filepath,
)
);
// Echo results
if ($result){
echo $result['ObjectURL'];
} else{
echo "fail";
}
Try this, it will surely work, the problem in your code is you haven't supplied credentials to factory function.
<?php
ini_set('display_errors', 1);
use Aws\S3\S3Client;
require 'vendor/autoload.php';
//here we are creating client object
$s3Client = S3Client::factory(array(
'credentials' => array(
'key' => 'YOUR_AWS_ACCESS_KEY_ID',
'secret' => 'YOUR_AWS_SECRET_ACCESS_KEY',
)
));
// Upload a file.
$filepath = '/var/www/html/aws3/test.txt';
$result = $s3Client->putObject(array(
'Bucket' => "myBucket",//some filebucket name
'Key' => "some_file_name.txt",//name of the object with which it is created on s3
'SourceFile' => $filepath,
'Endpoint' => 's3-eu-central-1.amazonaws.com',
'Signature' => 'v4',
'Region' => 'eu-central-1',
)
);
echo $result['ObjectURL'];

Upload to AWS S3 failing

I'm trying to upload a file from my Wordpress application to a S3 bucket by Ajax:
Somehow, I don't get an answer and the script fails with a 500 error when applying the 'putObject' method.
app/ajax.php
require_once 's3/start.php'
//wp_die(var_dump($s3)); Seems to be fine
$upload = $s3->putObject([
'Bucket' => $config['s3']['bucket'],
'Key' => 'video,
'Body' => fopen( $_FILES['file']['tmp_name'], 'r' ),
'ACL' => 'public-read',
]);
if ($upload) {
wp_die('Uploaded');
} else {
wp_die('Upload Error');
}
app/s3/start.php
use Aws\S3\S3Client;
require 'aws/aws-autoloader.php';
$config = require('config.php');
$s3 = new S3Client([
'key' => $config['s3']['key'],
'secret' => $config['s3']['secret'],
'region' => $config['s3']['region'],
'version' => 'latest',
]);
app/s3/aws
Latest version of the official AWS SDK for PHP
SOLUTION
The credentials in app/start.php where not assigned correctly when initialising the $s3 object. That's how it must look like
$s3 = S3Client::factory([
'region' => $config['s3']['region'],
'version' => 'latest',
'credentials' => [
'key' => $config['s3']['key'],
'secret' => $config['s3']['secret']
]
]);
If you upload a file, you should use SourceFile instead of Body.
Example code:
$result = $s3->putObject(array(
'Bucket' => $bucket,
'Key' => $keyname,
'SourceFile' => $filepath,
'ContentType' => 'text/plain',
'ACL' => 'public-read',
'StorageClass' => 'REDUCED_REDUNDANCY',
'Metadata' => array(
'param1' => 'value 1',
'param2' => 'value 2'
)
));
More info from here - http://docs.aws.amazon.com/AmazonS3/latest/dev/UploadObjSingleOpPHP.html

List objects in a specific folder on Amazon S3

I am trying to get the list of Object under a specific folder in my bucket.
I know that to get a list of all of my objects I do:
$objects = $client->getIterator('ListObjects', array(
'Bucket' => $bucket
));
I want to get only the objects under the folder my/folder/test. I have tried adding
'key' => "my/folder/test",
And
'prefix' => "my/folder/test",
But it simply returns all of the objects in my bucket.
You need to use Prefix to restrict the search to a specific directory (a common prefix).
$objects = $client->getIterator('ListObjects', array(
"Bucket" => $bucket,
"Prefix" => "your-folder/"
));
The answer is above however i figured i would supply a complete working example that can be copied and pasted directly into a php file and ran
use Aws\S3\S3Client;
require_once('PATH_TO_API/aws-autoloader.php');
$s3 = S3Client::factory(array(
'key' => 'YOUR_KEY',
'secret' => 'YOUR_SECRET',
'region' => 'us-west-2'
));
$bucket = 'YOUR_BUCKET_NAME';
$objects = $s3->getIterator('ListObjects', array(
"Bucket" => $bucket,
"Prefix" => 'some_folder/' //must have the trailing forward slash "/"
));
foreach ($objects as $object) {
echo $object['Key'] . "<br>";
}
"S3Client::factory is deprecated in SDK 3.x, otherwise the solution is valid" said by RADU
Here is the updated solution to help others who come across this answer:
# composer dependencies
require '/vendor/aws-autoloader.php';
//AWS access info DEFINE command makes your Key and Secret more secure
if (!defined('awsAccessKey')) define('awsAccessKey', 'ACCESS_KEY_HERE');/// <- put in your key instead of ACCESS_KEY_HERE
if (!defined('awsSecretKey')) define('awsSecretKey', 'SECRET_KEY_HERE');/// <- put in your secret instead of SECRET_KEY_HERE
use Aws\S3\S3Client;
$config = [
's3-access' => [
'key' => awsAccessKey,
'secret' => awsSecretKey,
'bucket' => 'bucket',
'region' => 'us-east-1', // 'US East (N. Virginia)' is 'us-east-1', research this because if you use the wrong one it won't work!
'version' => 'latest',
'acl' => 'public-read',
'private-acl' => 'private'
]
];
# initializing s3
$s3 = Aws\S3\S3Client::factory([
'credentials' => [
'key' => $config['s3-access']['key'],
'secret' => $config['s3-access']['secret']
],
'version' => $config['s3-access']['version'],
'region' => $config['s3-access']['region']
]);
$bucket = 'bucket';
$objects = $s3->getIterator('ListObjects', array(
"Bucket" => $bucket,
"Prefix" => 'filename' //must have the trailing forward slash for folders "folder/" or just type the beginning of a filename "pict" to list all of them like pict1, pict2, etc.
));
foreach ($objects as $object) {
echo $object['Key'] . "<br>";
}

Categories