carmelo arena
carmelo arena

Reputation: 561

Amazon S3 on Heroku with PHP

I would like to enable the use of my Amazon S3 bucket for my Heroku application.

Before Heroku, I was using s3fs to mount the directory directly. Now that this is not possible on Heroku, is there any other way to "link" them together, possibly by still keeping the upload (& resize) scripts still working?

Upvotes: 13

Views: 2319

Answers (3)

fuyi
fuyi

Reputation: 2639

You need to manually get the uploaded file and upload to S3, Keep in mind, Heroku has a read only file system, so you can not create temp file on Heroku app, every operation need to be done in memory.

Here is the S3 php api

A example:

// get uploaded file
$file = $_FILES['uploadedfile']['tmp_name'];

// do whatever manipulation on the file in memory
// $file = resize($file)

// upload file to S3, note, S3->putObjectFile won't work, as it require $file parameter to be string
if (S3::putObject(S3::inputFile($file), $bucket, $uri, S3::ACL_PRIVATE)) {
    echo "File uploaded.";
} else {
    echo "Failed to upload file.";
}

Update

it looks like S3 php lib does not have a api for uploading resource from memory, S3::inputFile need a string as input, not in memory resource. So the conclusion is: it it not possible to do so with S3 PHP client on Heroku

Upvotes: 0

borfast
borfast

Reputation: 2274

Depending on what your scripts do, you may have to change them a bit.

I should state first of all that I have never done this, so I could be missing some details, but from my experience with PHP, Heroku and S3, it should be as simple as accepting the uploaded file (which will be stored in a temporary directory somewhere on Heroku's server), resize it, and finally upload it to S3.

If you already had an upload workflow working, the only difference should be that instead of saving the file to a directory in your server (which, from what you say, was actually a sort of a symlink to an S3 bucket), you will now upload it to S3. You can do this easily with this library: https://github.com/tpyo/amazon-s3-php-class

Something like this:

// Ink is expensive, let's write less
$file = $_FILES['uploadedfile']['tmp_name'];
$name = $_FILES['pictures']['name'];

// Resize the image
resize($file);

// Normally you would do this for storing the file locally
// move_uploaded_file($file, "$destinationdir/$name");

// Now you want to upload to S3
$s3 = new S3($awsAccessKey, $awsSecretKey);
$s3->putObject($s3->inputFile($file, false), $bucketName, $uploadName, S3::ACL_PUBLIC_READ)

Depending on how you organise your uploads, you may also want to keep a record of the bucket name and the file name, maybe in a database table where you can search for the file name and get the bucket name, because you will need both to retrieve the file.

Upvotes: 1

Benjamin Tan Wei Hao
Benjamin Tan Wei Hao

Reputation: 9691

I guess that should still be possible. Have you taken a look at Using AWS S3 to Store Static Assets and File Uploads?

Upvotes: 1

Related Questions