Would uploading to S3 using SQS make the process more fault tolerant?
If so, i am having a hard time with syntax, trying to combine creating a queue then uploading to S3.If my logic is not correct, how would i set up a system using SQS to upload to S3?
if (!class_exists('S3'))require_once('S3.php');
// *these keys are random strings
$AWS_KEY = "6VVWTU4JDAAKHYB1C3ZN";
$AWS_SECRET_KEY = "GMSCUD8C0QA1QLV9Y3RP2IAKDIZSCHRGKEJSXZ4F";
//AWS access info
if (!defined('awsAccessKey')) define('awsAccessKey', $AWS_KEY);
if (!defined('awsSecretKey')) define('awsSecretKey', $AWS_SECRET_KEY);
//instantiate the class
$s3 = new S3(awsAccessKey, awsSecretKey);
//check whether a form was submitted
if(isset($_POST['Submit'])){
//retreive post variables
$fileName = $_FILES['theFile']['name'];
$fileTempName = $_FILES['theFile']['tmp_name'];
//create a new bucket
$s3->putBucket("mybucket", S3::ACL_PUBLIC_READ);
//add the queue
$sqs = new AmazonSQS(array( "key" => $AWS_KEY, "secret" => $AWS_SECRET_KEY ));
$response = $sqs->create_queue('test-topic-queue');
$queue_url = (string) $response->body->CreateQueueResult->QueueUrl;
$queue_arn = 'arn:aws:sqs:us-east-1:ENCQ8gqrAcXv:test-topic-queue';
//$queue_url . ?Action=SendMessage&MessageBody=Your%20Message%20Text?&AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&Version=2011-10-01?&Expires=2008-02-10T12:00:00Z?&Signature=lBP67vCvGlDMBQ1do?fZxg8E8SUEXAMPLE&SignatureVersion=2&SignatureMethod=HmacSHA256
// HOW DO I INCORPORATE SQS AND S3
//move the file
if ($s3->putObjectFile($fileTempName,
"mybucket",
"myFolder/" . $fileName, S3::ACL_PUBLIC_READ,
array(),
$_FILES['theFile']['type']) ) {
//it works
}else{
// error
}
}
I'm not exactly understanding the fault tolerance you are requesting. But in terms of using S3 and SQS for scaling, there is an excellent paper on the Amazon AWS website that talks about scaling up and down your infrastructure using SQS and EC2 together, which can of course include processes like uploading to S3 and using SQS to tell the application to process something. You don't mention whether or not you're using EC2 or if this is of interest.
Here is the article: http://aws.amazon.com/articles/1464
Otherwise, it sounds like your logic may be confused as SQS isn't an in-between from server to S3, but rather more for application messaging.
I think i figured out the OP's confusion on this topic.
The diagram shown makes it appear that SQS is handling uploads, but its really not, when you upload 1 or 100 photo's, they're added to S3 directly, then using SQS it creates a "Task" which one of the EC2 "Processing Servces" will pull, and then grab the actual picture from the S3 storage that as named in the SQS message.
Hopefully this gives some insight for future users who see this question feeling lost.
Related
I'm trying to display images from my AWS S3 bucket using PHP, I can succesfully retrieve the object Key and display it on my website using PHP but I dont know how to display the file it self.
require './vendor/autoload.php';
use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;
// AWS Info
$bucketName = '#';
$IAM_KEY = '#';
$IAM_SECRET = '#';
// Connect to AWS
try {
$s3 = S3Client::factory(
array(
'credentials' => array(
'key' => $IAM_KEY,
'secret' => $IAM_SECRET,
),
'version' => 'latest',
'region' => 'eu-west-2'
)
);
} catch (Exception $e) {
die("Error: " . $e->getMessage());
} $result = $s3->listObjects(array('Bucket' => $bucketName));
echo "Keys retrieved!\n";
foreach ($result['Contents'] as $object) {
echo $object['Key'] . "\n";
echo '<img src="'.$result .'">'
}
Any help or points in the right direction would be much appreciated.
One should have a web server to serve the images.
Use the S3 native website support - make the bucket public - very easy.
https://docs.aws.amazon.com/AmazonS3/latest/userguide/WebsiteHosting.html
But be mindful that all of the objects in the bucket become public.
If one wants to protect the content, use presigned URLs
https://docs.aws.amazon.com/AmazonS3/latest/userguide/ShareObjectPreSignedURL.html
Set up CloudFront in front of the S3 to act as CDN for fast content delivery.
https://aws.amazon.com/blogs/networking-and-content-delivery/amazon-s3-amazon-cloudfront-a-match-made-in-the-cloud/
CloudFront also supports predesigned URLs so that one can protect the content.
Maybe the heaviest and error-prone; copy the objects locally on the server or to a shared file system (like EFS) and serve them from the same server with the php. While this is an option, I would not generally recommend it.
The usual approach is the have a CloudFront routing.
https://aws.amazon.com/blogs/networking-and-content-delivery/deliver-your-apps-dynamic-content-using-amazon-cloudfront-getting-started-template/
a) Dynamic content to the web server with PHP (there might be many servers behind an ALB for scaling or a single server)
b) Static content to S3
I'm fairly new to writing in PHP and I've hit a snag while developing a Google Drive connection. I'm trying to create a small widget for a WordPress site wherein users on the site can upload and download files from their Google Drives.
These users are from a closed GSuite Domain and I use a Domain-Wide Service account in order to authenticate and connect to the user's drives.
I am able to connect, retrieve a list of files, and successfully "download" a files contents, though, this download does not actually download a file to the computer, simply returns the contents.
References:
-Uploading: https://developers.google.com/drive/api/v3/manage-uploads
-Downloading: https://developers.google.com/drive/api/v3/manage-downloads
-- I need to place a download button on my page which will allow a user to select a file and download it to their computer without saving it on the server. Currently it just returns the content of the file which I can store in a variable, but I do not know how to have a client request it and download it.
I need an upload button as well but I am working on a solution that I believe will work. I've read many different articles suggesting Ajax, Node, etc...
Ajax:
Calling a PHP function from an HTML form in the same file?
Upload UI:
https://www.htmlgoodies.com/beyond/cms/create-a-file-uploader-in-wordpress.html
In my client initialization file:
$client = new Google_Client();
$client->useApplicationDefaultCredentials();
$client->addScope(Google_Service_Drive::DRIVE);
$client->setSubject($user_to_impersonate);
$driveService = new Google_Service_Drive($client);
return $driveService;
In the php script that loads the widget on the page:
$drive_connection = getUserGoogleDriveService();
$retrieved_files = array();
$filesList = $drive_connection->files->listFiles();
foreach($filesList->files as $file)
{
array_push($retrieved_files, array(
'filename' => $file->name,
'fileid' => $file->id,
'file' => $file
));
}
$get_specific_file = array_search('example_file_name',
array_column($retrieved_files, 'filename'));
Edit: I added my code thus far. This code successfully lets me store and retrieve files from my array for further use. How would I tie this into a client side UI to upload files to the google "create" function.
i am in the proccess of creating a "Content Management System" for a "start up company". I have a Post.php model in my project, the following code snippet is taken from the Create method:
if(Request::file('display_image') != null){
Storage::disk('s3')->put('/app/images/blog/'.$post->slug.'.jpg', file_get_contents(Request::file('display_image')));
$bucket = Config::get('filesystems.disks.s3.bucket');
$s3 = Storage::disk('s3');
$command = $s3->getDriver()->getAdapter()->getClient()->getCommand('GetObject', [
'Bucket' => Config::get('filesystems.disks.s3.bucket'),
'Key' => '/app/images/blog/'.$post->slug.'.jpg',
'ResponseContentDisposition' => 'attachment;'
]);
$request = $s3->getDriver()->getAdapter()->getClient()->createPresignedRequest($command, '+5 minutes');
$image_url = (string) $request->getUri();
$post->display_image = $image_url;
The above code checks if there is a "display_image" file input in the request object.
If it finds a file it uploads it directly to AWS S3 storage. I want to save the link of the file in the Database, so i can link it later in my views.
Hence i use this piece of code:
$request = $s3->getDriver()->getAdapter()->getClient()->createPresignedRequest($command, '+5 minutes');
$image_url = (string) $request->getUri();
$post->display_image = $image_url;
I get a URL, the only problem is that whenever i visit the $post->display_image URL i get a 403 permission denied. Obviously no authentication takes place when using the URL of the image.
How to solve this? I need to be able to link all my images/files from amazon S3 to the front-end interface of the website.
You could open up those S3 URLs to public viewing, but you probably wouldn't want to. You have to pay for the outgoing bandwidth every time someone views one of those images.
You might want to check out Glide, a pretty simple-to-use image library that supports S3. Make sure to reduce the load requirements on your server and wallet by setting caching headers on the images you serve.
Alternatively, you could use a CloudFront distribution as a caching proxy in front of your S3 bucket.
I have a website hosted on amazon. I want my clients to give access to upload files that are already in their amazon s3 space to my s3 space. Is there any php API that supports this functionality?
Amazon actually provides one. And there are lots of examples on the web of using it. Google is your friend.
Amazon have a PHPSDK , check the sample code
// The sample code below demonstrates how Resource APIs work
$aws = new Aws($config);
// Get references to resource objects
$bucket = $aws->s3->bucket('my-bucket');
$object = $bucket->object('image/bird.jpg');
// Access resource attributes
echo $object['LastModified'];
// Call resource methods to take action
$object->delete();
$bucket->delete();
Or use old s3.php for uploading files to s3 bucket. its a single php file named s3.php
You just download that and from your code . for more read this.
<?php
if (!class_exists('S3'))require_once('S3.php');
//AWS access info
if (!defined('awsAccessKey')) define('awsAccessKey', 'YourAccess S3 Key');
if (!defined('awsSecretKey')) define('awsSecretKey', 'Yor Secret Key');
//instantiate the class
$s3 = new S3(awsAccessKey, awsSecretKey);
$s3->putBucket("bucket name", S3::ACL_PRIVATE);
//move the file
if ($s3->putObjectFile("your file name in the server with path", "which bucket ur using (bucket name)", "fine name in s3 server", S3::ACL_PRIVATE)) {
//s3 upload success
}
?>
I need to display videos / images file with ACL:PRIVATE uploaded to my Amazon S3 account on my wordpress blog.
I am a newbie to PHP oops based coding. Any script help, link references, free plugins or even Logical Algorithm will be great help :)
Thanks in advance.
This issue could be solved by implementing the following steps:
Download latest stable version of SDK from here
Extract the .zip file & place in wamp/www folder
Rename config-sample.inc.php file to config.inc.php
Add the access key & secret key (retrieved from Amazon S3 account) into above file, save & exit
create a sample file to display public / private objects from Amazon S3
The content of the file should look as follows:
require('sdk.class.php');
require('services/s3.class.php');
$s3 = new AmazonS3();
$bucket = "bucketname";
$temp_link = $s3->get_object_url($bucket, 'your/folder/path/img.jpg', '5 minute');
echo $temp_link;
In above code, the URL you receive as output is a signed URL for your private object, thus it is valid only for 5 minutes.
You may grant access for a future date and allow only authorized users to access your private content or media on Amazon S3.
This question is a little bit old, but I'm posting it anyway. I had a simliar issue today and found out there's a simple answer.
aws doc explains it clearly and has an example as well.
http://docs.aws.amazon.com/aws-sdk-php-2/guide/latest/service-s3.html#amazon-s3-stream-wrapper
Basically, you need to register AWS' stream wrapper and use s3:// protocol.
Here's my code sample.
use Aws\Common\Aws;
use Aws\S3\Enum\CannedAcl;
use Aws\S3\Exception\S3Exception;
$s3 = Aws::factory(array(
'key' => Config::get('aws.key'),
'secret' => Config::get('aws.secret'),
'region' => Config::get('aws.region')
))->get('s3');
$s3->registerStreamWrapper();
// now read file from s3
// from the doc.
// Open a stream in read-only mode
if ($stream = fopen('s3://bucket/key', 'r')) {
// While the stream is still open
while (!feof($stream)) {
// Read 1024 bytes from the stream
echo fread($stream, 1024);
}
// Be sure to close the stream resource when you're done with it
fclose($stream);
}