Using S3 to upload in PHP using PHP DI - php

I am using dependency injector to setup S3's credentials:
// AWS S3 for PDF
$container['s3_pdf'] = function ($c) {
// Only load credentials from environment variables.
$provider = CredentialProvider::env();
$s3 = new Aws\S3\S3Client([
'version' => 'latest',
'region' => 'ap-southeast-2',
'credentials' => $provider
]);
return $s3;
};
Then whenever I want to upload something I'd do:
$result = $this->s3_pdf->putObject(array(
'Bucket' => 'reports.omitted.com',
'Key' => 'temptest1.pdf',
'SourceFile' => 'assets/temp.pdf',
'ContentType' => 'text/plain',
'ACL' => 'public-read',
'StorageClass' => 'REDUCED_REDUNDANCY',
'Metadata' => array(
'param1' => 'value 1',
'param2' => 'value 2'
)
));
I want to be able to upload to S3 from different functions in the code without having to write the bucket name everytime, am I able to have the s3_pdf container return a function that only takes sourcefile and runs some code to figure out the sourcefile & destination & uploads to S3?
I know that I can use a class that would contain this function I'm after and use an object of that class in the functions where I need S3 but I'd rather use the dependency container if there is a way to do so.

This is the simplest example of my suggested wrapper function possible:
class WhateverYourClassIs
{
function putObject( $key, $sourceFile )
{
return $this->s3_pdf->putObject(array(
'Bucket' => 'reports.omitted.com',
'Key' => $ke,
'SourceFile' => $sourceFile,
'ContentType' => 'text/plain',
'ACL' => 'public-read',
'StorageClass' => 'REDUCED_REDUNDANCY',
'Metadata' => array(
'param1' => 'value 1',
'param2' => 'value 2'
)
));
}
}
Or with an array
class WhateverYourClassIs
{
function putObject( $overloadedConfig )
{
$baseConfig = array(
'Bucket' => 'reports.omitted.com',
'Key' => NULL,
'SourceFile' => NULL,
'ContentType' => 'text/plain',
'ACL' => 'public-read',
'StorageClass' => 'REDUCED_REDUNDANCY',
'Metadata' => array()
);
return $this->s3_pdf->putObject( array_merge_recursive( $baseConfig, $overloadedConfig ) );
}
}
$this->putObject(array(
'Key' => 'temptest1.pdf',
'SourceFile' => assets/temp.pdf'
));

Related

AWS S3 URL is different from the original one

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
));

AWS S3 file upload using cakephp 3

I'm trying to implement file upload to amazon s3. I'm getting following error
Cannot redeclare GuzzleHttp\uri_template() (previously declared in /var/www/html/appname/vendor/guzzlehttp/guzzle/src/functions‌​.php:17) File /var/www/html/appname/vendor/aws/GuzzleHttp/functions.php
In upload controller, using below code to upload
require_once("../vendor/aws/aws-autoloader.php");
use Aws\S3\S3Client;
public function upload(){
$s3 = S3Client::factory(array( 'version' =>
'latest', 'region' => 'ap-south-1', 'credentials' => array(
'key' => 'key',
'secret' => 'secret' ) ));
if ($this->request->is('post'))
{
if(!empty($this->request->data['file']['name']))
{
$fileName = $this->request->data['file']['name'];
$s3->putObject([
'Bucket' => backetname,
'Key' => $fileName,
'SourceFile' => $this->request->data['file']['tmp_name'],
'ContentType' => 'image/jpeg',
'ACL' => 'public-read',
'StorageClass' => 'REDUCED_REDUNDANCY'
]);
}
}
}
You are creating an object of S3 client outside of the method which is the reason that $s3 in method is null.
Either you need to create object in method itself or you can store the S3 client object in class property and use with $this->s3->putObject()
Better would be to create a component, something like below:
<?php
namespace App\Controller\Component;
use Cake\Controller\Component;
use Aws\S3\S3Client;
class AmazonComponent extends Component{
public $config = null;
public $s3 = null;
public function initialize(array $config){
parent::initialize($config);
$this->config = [
's3' => [
'key' => 'YOUR_KEY',
'secret' => 'YOUR_SECRET',
'bucket' => 'YOUR_BUCKET',
]
];
$this->s3 = S3Client::factory([
'credentials' => [
'key' => $this->config['s3']['key'],
'secret' => $this->config['s3']['secret']
],
'region' => 'eu-central-1',
'version' => 'latest'
]);
}
}
And use this component in your controller. Example below:
class UploadController extends AppController{
public $components = ['Amazon'];
public function upload(){
$objects = $this->Amazon->s3->putObject([
'Bucket' => backetname,
'Key' => $fileName,
'SourceFile' => $this->request->data['file']['tmp_name'],
'ContentType' => 'image/jpeg',
'ACL' => 'public-read',
'StorageClass' => 'REDUCED_REDUNDANCY'
]);
}
}

Method Aws\S3\S3Client::putObject() does not exist

In my application i am trying to upload the image to amazon S3 bucket from local directory which is getting upload first.When i am uploading the file i am getting the error.I don't have any idea what to change.Is there anything to change or add in vendor? please help.
Controller:
$s = new Storage();
$result = $s->upload($bucket,$keyname,$filepath);
models\Storage.php:
<?php
namespace app\models;
use Yii;
use yii\base\Model;
class Storage extends Model
{
private $aws;
private $s3;
function __construct() {
$this->aws = Yii::$app->awssdk->getAwsSdk();
$this->s3 = $this->aws->createS3();
}
public function upload($bucket,$keyname,$filepath) {
$result = $this->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'
)
));
return $result;
}
The error is below:
An Error occurred while handling another error:
exception 'ReflectionException' with message 'Method
Aws\S3\S3Client::putObject() does not exist' in
D:\xampp\htdocs\teespring-testmailer\vendor\yiisoft\yii2\web\ErrorHandler.php:195
I have given the wrong region name in config\web.php.That is the problem.I changed the region then it works well.
'awssdk' => [
'class' => 'fedemotta\awssdk\AwsSdk',
'credentials' => [ //you can use a different method to grant access
'key' => 'XXXXXXXXXXXXXXXXX',
'secret' => 'XXXXXXXXXXXXXXXXXXXXX',
],
'region' => 'us-west-2', //before 'us-east-1'
'version' => 'latest',
],

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

Categories