How to Use Amazon S3 & PHP to Dynamically Store and Manage Files with Ease

Tutorial Details
  • Difficulty: Intermediate
  • Completion Time: 30 Minutes

A couple of weeks ago, Nettuts+ posted an introductory tutorial to using Amazon’s Simple Storage System (S3). Being able to upload an unlimited number of files for hardly any money is great, but it would be even better if your users could upload files from your website. That way you wouldn’t have to worry about the size of your web server for a second. Let’s try!

Basically what we’re going to do is use a standard HTML file element and an easy to use S3 PHP class to make a page where people can upload a file to your S3 account and get information about the files that have already been uploaded. For this you’ll need an Amazon S3 account and a PHP enabled webserver. If you haven’t heard about Amazon S3, or you don’t have an account yet, read Collis’ Introductory S3 Tutorial first.

Step 1

Now, the first thing we’ll need is a way for PHP to communicate with the S3 server. Donovan Schonknecht has written a PHP class for this, so rather than trying to reinvent the wheel, we’ll use that!

  1. Download the ‘latest beta version (0.2.3)’
  2. Extract the .rar file and copy the S3.php file to a new folder. The file comes with a readme and a few examples, too, but we won’t be using those.
  3. Open the S3.php file and take a look around just to see all the work you will not be doing yourself thanks to this class! :-)

Step 2

Next, make a new file called page.php in the same folder. First thing we’ll need to do is include the S3.php file. We’ll use the require_once() function in php. This function will include the file only if it wasn’t included before on the same page. This is to make sure that we won’t run into any problems with function redefinitions when accidentally the script tries to include the file a second time.

Next, we’ll have to enter the Amazon Web Services (AWS) access information the script needs to access our S3 server. These are the Acces Key and the Secret Key provided by Amazon (again, if you don’t know what I’m talking about see the introductory NETTUTS tutorial). Now we have all the information needed to initiate the class. This code was put in the very top of the body tags.

<?php
//include the S3 class				
if (!class_exists('S3'))require_once('S3.php');

//AWS access info
if (!defined('awsAccessKey')) define('awsAccessKey', 'CHANGETHIS');
if (!defined('awsSecretKey')) define('awsSecretKey', 'CHANGETHISTOO');

//instantiate the class
$s3 = new S3(awsAccessKey, awsSecretKey);

//we'll continue our script from here in step 4!

?>

Step 3

Now let’s make a simple html form with a file element in it. This element allows users to browse their local drive for a file. When the user presses the submit button the file will automatically be uploaded as a temporary file to the server and information about the file will be sent in the POST variable.

Here’s the code snippet. Be sure not to forget enctype="multipart/form-data" which is necessary for the file element to work. This code should be placed outside the <?php ?> tags, since it is HTML.

<form action="" method="post" enctype="multipart/form-data">
  <input name="theFile" type="file" />
  <input name="Submit" type="submit" value="Upload">
</form>

Step 4

Now, for those unfamilliar with forms, action="" tells the script which page to go to after submitting. Since we specified an empty string there, the form will post the variables and then refresh the current page. So when the page gets loaded, we’ll want to check whether or not a form was submitted.When a form was submitted the page should execute the script that retreives the post variables and takes care of moving the files to the S3 server.

The post variable sent by the file element is an array, containing information about the file. For example: filename, size, type and temporary name. All we’ll need is the filename and the temporary name. Note that, unlike other form elements, the file element will send the variables to $_FILES and not to $_POST.

The PHP code below checks whether a form was submitted and retreives the post variables. We’ll deal with the S3 server later. This code should be placed right after where we initiated the s3 class.

//check whether a form was submitted
if(isset($_POST['Submit'])){

    //retreive post variables
    $fileName = $_FILES['theFile']['name'];
    $fileTempName = $_FILES['theFile']['tmp_name'];
	
    //we'll continue our script from here in the next step!
}

Step 5

Ok, so now we have a form that sends a temporary file to the server and leaves you with some information. If you like, you can upload the file to a server and test it. You’ll notice that it indeed takes some time to process the form, since it is in fact uploading a file. Anyway, you won’t see the file appear anywhere on your server because it was only stored as a temporary file. All that’s left to do is to move our uploaded file to a bucket. First we’ll create a new bucket and then we’ll move the file to that bucket.

To create a bucket we’ll use the function putBucket(bucket, acl) in which ‘bucket’ is the name of the bucket (Amazon’s word for your main folder or directory of files). The second argument is the Access Control List (ACL) in which you can define who can and who cannot read from or write to this bucket. We want anybody to be able to read our files, so we’ll use S3::ACL_PUBLIC_READ. Note that a bucket only needs to be created once, so every next time this script is executed this function won’t do anything, since the bucket already exists.

To move the file we’ll use the function putObjectFile(sourcefile, bucket, newfilename, acl).The sourcefile is the path to the file we want to move, so in our case it is the temporary file that was uploaded through our form. Bucket is the bucket to move the file to, which will be the bucket we just created. Newfilename is the filename the file will get in the bucket. In this tutorial we’ll use the same filename as on the local drive, but in some cases you might want to change filenames. Acl again is the Access Control List, which we’ll again set to S3::ACL_PUBLIC_READ.

//create a new bucket
$s3->putBucket("jurgens-nettuts-tutorial", S3::ACL_PUBLIC_READ);

//move the file if ($s3->putObjectFile($fileTempName, "jurgens-nettuts-tutorial", $fileName, S3::ACL_PUBLIC_READ)) { echo "We successfully uploaded your file."; }else{ echo "Something went wrong while uploading your file... sorry."; }

Step 6

Now when you select a file and hit ‘Upload’ the file will be stored on the amazon server. You can already view it just by entering a URL that looks like this: http://yourbucketname.s3.amazoneaws.com/yourfile.ext

For the finishing touch we’ll want the script to output a list of files in the bucket. For this we’ll use the function getBucket(bucket), in which bucket is the bucket we want to output. This function returns an array with information about the files. Each returned as an array, too. To visualize:

We want to output every file in the $bucket_contents array. For this we’ll use a foreach() loop which will loop through the array until all elements have been processed. It will store the current element in the $file variable and execute the code in between the brackets. All we need to do now is echo a link to the file.

Place this code under the form to show the list there.

<?php
// Get the contents of our bucket
$bucket_contents = $s3->getBucket("jurgens-nettuts-tutorial");

foreach ($bucket_contents as $file){

    $fname = $file['name'];
    $furl = "http://jurgens-nettuts-tutorial.s3.amazonaws.com/".$fname;
    
    //output a link to the file
    echo "<a href=\"$furl\">$fname</a><br />";
}
?>

With a little css styling, your final result might look like this:

Finished!

So there you have it, your own unlimited file upload script. Of course there’s a lot more you can do with the S3 PHP class. Just take a quick glance at its readme file and you’ll be good to go. It’s really easy to use!

Download the source files

View a demo

Tags: amazon
Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • ives

    I can create sub folder from the aws s3 console, but I can’t find how to create folder by this sdk. I can upload a file to the bucket and sub folder by this code after I create a sub folder at aws console, so can anyone can share the code of create sub folder?

    Thanks.

  • ives

    I can create sub folder by aws console, but how can I create it from this sdk? I also can upload a file to the bucket’s sub folder after I create this sub folder from aws console. Can anyone share the code to create a sub folder use this sdk of php?

    Thanks.

  • http://www.wildpeaks.com Cecile Muller

    @Jadamster:

    If you know the path in the bucket, you can download the file individually, for example:

    $s3->getObject(‘mybucket’, $uploadName, fopen(‘savefile.txt’, ‘wb’));

    —-

    @ives:
    It automatically creates the folder(s) if you specify a path with folders in it, for example:

    $s3->putObject($s3->inputResource(fopen($filename, ‘rb’), filesize($filename)), ‘mybucket’, ‘subfolder/’ . $filename, S3::ACL_PUBLIC_READ, array(), array(), S3::STORAGE_CLASS_RRS);

    I’m not sure how to delete folders programatically however.

    —-

    Btw, it could be better to point to the Github repo of the library (as location to download from) than the 2007 blog post:

    https://github.com/tpyo/amazon-s3-php-class

  • http://www.nadworks.com Nadja von Massow

    The demo comes up with a 404 error :o(

  • http://wyattarent.com Wyatt

    Quick question

    My S3 Server will have a ton of files on it, and many will share the same name
    When I want to pull a specific file from the server, I access it via hash

    But, when I want to delete a file from the server, it appears you can only delete it by file name.

    If I try to delete a file by file name, wouldn’t that in turn delete every single file in the bucket that shares the same name?

    If so, isn’t there a way to delete a file on the server by hash to avoid this problem?

    Thank you for your time

    • http://bighugefile.com Jason

      I use the hash method as well to avoid filename collisions on Bighugefile.com. I accomplish this by renaming the uploaded file file to “[hash]/[filename]“, and then uploading it to S3 via putObjectFile(). This way, S3 actually sees the filename as “[hash]/[filename]“. Adding the “/” between the hash and the original filename causes S3 to treat this as folder/file, with the hash being the unique folder name. This allows me to preserve the original filename while maintaining a unique hashed structure. When I get ready to delete the file(s), I simply pass “[hash]/[filename]” as the filename to the S3 deleteObject() call. This deletes both the hashed folder and the original file. I hope this makes sense.

    • http://wyattarent.com Wyatt

      Sorry, please disregard my last comment. I was on about 2 hours of sleep when I made it.
      Obviously you can’t have multiple files of the same name in the same bucket, that’s just silly

      Thanks

  • Frustrated

    When i browse to http://mybucket.s3.amazonaws.com/page.php the browser is asking for downloading the file!!????

    How do you “run” the file?

    NO ONE has this problem??

    • http://www.villas-and-prestige.com Dimitri

      Hello,
      Amazon S3 do not manage php files.
      It is NOT a php server.

      S3 only serve static files (.html)

      Regards
      Dimitri

  • Dayan

    This is a great tutorial, I would really appreciate this work.

    I can successfully upload my local files to the aws.amazon bucket and it works for me.

    But i have one thing to ask, this work is not little bit matching my requirements, I have my data (Video files) on an other sever call it “Betterencoding” server, this server is used for encoding videos and that server just provide a direct link for download after encoding, please check this ( http://v4.betterencoding.com/download?date=10-12-2011&filename=tool.mp4 ). So i want to move these encoded file directly to amazon bucket.

    How can i interlink this direct link to upload data to amazon bucket? As this tutorial only allows upload from local machine.

    I would be very thankful, if you could provide some alternate solution for my this above issue.

    May thanks in advance and any help would be appreciated.

    Dayan

  • http://www.friendsreunited.co.uk/blog/read/719786840/167091 Bradley Heinecke

    Just desire to say your article is as amazing. The clearness in your post is just spectacular and that i can suppose you are knowledgeable on this subject. Well along with your permission allow me to grasp your feed to keep up to date with approaching post. Thanks one million and please carry on the rewarding work.

  • Pingback: PHP & S3 | Dan Harabagiu

  • Ollie Armstrong

    Fantastic article, still relevant three years after publish date.

  • sudhir

    Its actually great tutorial helped a lot.
    But can i upload large files in chunks so that even if connection fails i can continue the uploading.
    Please help.

  • http://applemacbookproreviewbuy.blogspot.com/ chai

    Hi, Demo can not show.

  • Vishal

    Hi

    How do I upload files to existing bucket? It fails if I use $s3->putObjectFile

    Existing bucket permission is set to public (i.e Everyone > List is ticked and upload/delete is ticked too)

    Please help

    Thanks
    Vishal

  • http://www.sfgate.com/cgi-bin/contribute/sn/persona?User=hansgross123&plckController=PersonaBlog&plckScript=personaScript&plckElementId=personaDest&plckPersonaPage=BlogViewPost&plc Taylor Alviar

    I just could not go away your web site before suggesting that I extremely loved the usual information a person supply in your visitors? Is going to be back ceaselessly to check out new posts

  • Murta

    I can’t upload ANY file with more than 1.2Mb!…. Does someone know what’s happening? I really can’t understand what’s going on… HELP!
    =]

  • Guest

    Um,

    if (!class_exists(‘S3′))require_once(‘S3.php’);

    da fuk? Redundant. K. Thx.

  • http://www.comedydotcom.com Scott

    This may be just the ticket for me! I host a comedy booking agency site. I have lots of comedians to hire shown on the site. I want to include videos from the comedians. This script will allow me to do it – I think. I need to figure out how I will be able to tell who each on is from. Comedians as a rule are not computer savvy. But, I will certainly play with with this.

    Thanks very much for sharing!

  • Brad

    Does this method for S3 uploading pass the actual secret key to the server? or is their anyway to run it through a config file?

  • http://dev.allabouttrucks.us/S3AWS/page.php ravi

    iam unable to connect o s3 using php code what are all the changes to be done in s3 class what are the files do ineed to download to copy files from php code to s3 server

  • http://dev.allabouttrucks.us/S3AWS/page.php ravi

    can anyone give me a complete reference link or example to use amazons3 from my server using php code to upload files into s3.

  • http://www.funnybunnyvideos.in/ Faraz Frank

    How to check whether my aws-access-key or aws-secret-key is valid or not?

    am trying these 2 codes:
    CODE-1. (if both key right/wrong)
    —————–
    $S3 = new S3($_POST['aws_access_key'], $_POST['aws_secret_key']);
    print_r($S3);
    die;
    —————–
    It returns: S3 Object ( )

    CODE-2 (if both key right/wrong)
    —————–
    $S3 = new S3();
    $var = S3::setAuth($_POST['aws_access_key'], $_POST['aws_secret_key']);
    print_r($var);
    die;
    —————–
    It returns: nothing

    Question is, I want to save my keys in db if these are correct???

    Problem: when i post wrong keys its return nothing, so how can i check is it a valid or invalid? i need a response or error to decide its wrong or right login credential for amazon S3.

  • http://www.viralplanet.co.uk Cam

    Excellent article full credit to the author very useful even now. Easy to follow and simple. Have used it on viralplanet.co.uk

  • Pingback: upload file to amazon S3 with codeigniter/php | PHP Developer Resource

  • Pingback: How to Use Amazon S3 & PHP to Dynamically Store and Manage Files with Ease | Nettuts+ » Web Design

  • http://www.funnybunnyvideos.in/ Frank Faraz

    Hi
    Am using your tutorial for Amazon-S3 and get these error when trying to download file(object) by click on download link.

    Code:

    All uploaded files
    getBucket(“nalin_gehlot”);
    foreach ($contents as $file){

    $fname = $file['name'];
    $furl = “http://nalin_gehlot.s3.amazonaws.com/”.$fname;

    //output a link to the file
    echo “$fname“;
    }
    ?>

    Error:

    This XML file does not appear to have any style information associated with it. The document tree is shown below.
    AccessDeniedAccess DeniedA712963E49C407B3mUFkVjE6+FPpGuMvLcXlMHLD9jqEiLSQ6Zo5arvEacFA/k+1X/xQgFGmfgYGruca

    • http://www.funnybunnyvideos.in/ Faraz Frank

      Code

      All uploaded files
      getBucket(“nalin_gehlot”);
      foreach ($contents as $file){

      $fname = $file['name'];
      $furl = “http://nalin_gehlot.s3.amazonaws.com/”.$fname;

      //output a link to the file
      echo “$fname“;
      }
      ?>

      Error:

      This XML file does not appear to have any style information associated with it. The document tree is shown below.
      AccessDeniedAccess DeniedA712963E49C407B3mUFkVjE6+FPpGuMvLcXlMHLD9jqEiLSQ6Zo5arvEacFA/k+1X/xQgFGmfgYGruca

      • jsonx

        You need to give right permission to access files as public.
        If you use S3 console click Properties and add Grantee: Everyone [check] Open/Download
        If you upload your files by using S3 class make sure that you have the S3::ACL_PUBLIC_READ parameter.

  • kapil

    How Can I resize and change format of image before uploading image into amazon S3?

  • Manender

    how to upload file ina folder inside the bucket
    e.g bucketname/foldername/file.txt

    • jsonx

      just put your $fileName as “bucketname/foldername/file.txt”

  • Amy

    Is there a way to use this so the list of uploaded files is passed to a different page and to make sure that the file is validated to be a certain file type?

  • jsonx

    Thank you very much for the great and clean tutorial.

  • Ross Helfer

    Great work! I have been able to test this out on my server and it’s working great except I can’t upload anything larger then a 2meg file. Can you please tell mr what I may be doing wrong or have set incorrectly.

    Thanks in advance,
    Ross

  • Refl

    i used this code in my site.But i was not able to upload files more than 100mb.

    I am Using host gator shared server. Is my server ‘s maximum upload limit or maximum execution time causing this upload to fail

  • Pingback: How to use Amazon S3 for persistent file storage on AppFog - Platform as a Service Magazine

  • Pushpinder Bagga

    Great. Thanks a lot!

  • http://www.facebook.com/dimitar.danailov Димитър Данаилов

    Thanks for great article !!!

  • Rico

    Great article! It helped me a lot. Thanks. I was wondering, does the temporary file get stored on your own server or on the Amazon server?

  • Kavyansh

    Very helpful article for PHP Developers who want to get started with Amazon Storage htttp://www.kws.co.in

  • Shaheen Pathan

    Thanks a Lot…..Its really helpful artical..

  • Tim

    I get the error:

    Warning: S3::getBucket(): [PermanentRedirect] The bucket you are
    attempting to access must be addressed using the specified endpoint.
    Please send all future requests to this endpoint.

    I’m using an EU / Ireland bucket so have changed the static variable $endpoint in S3.php to ‘s3-eu-west-1.amazonaws.com’ as Amazon (and various forums) point out. I still get the error though.

    Any ideas?
    Thanks

    • Kieran

      Hi there,
      I’m getting the same issue. Did you resolve this in the end?

  • Pradeep Kumar KN

    Very good article

  • Cedonio

    I have a config file in my web application that defines an upload dir within my web server, i.e.
    ‘upload_dir’ => ‘upload/’

    I want to be able to use S3 as the upload/ dir for my application. How do I go about using it as a mounted drive? Any direction will be greatly appreciated.