Click here to Skip to main content
15,881,715 members
Articles / Programming Languages / PHP

PHP AWS SDK (S3)

Rate me:
Please Sign up or sign in to vote.
4.33/5 (2 votes)
4 Feb 2011CPOL2 min read 40.9K   536   9   5
Using the PHP AWS SDK (S3) to upload and show private files.

Introduction

This code allows you to upload files to Amazon S3, keep them private (in other words, not have them visible/downloadable simply from a S3 URL), but have them accessible from your own web pages.

Background

This project uses the ideas from Donovan Schönknecht and Nettuts+ as points of departure. Donovan has written a S3 PHP interface and Nettuts+ has used his code to implement uploading images and showing hyperlinks to the uploaded images.

This implementation uses the AWS SDK PHP code from Amazon instead of Donovan's code, and keeps the files private as opposed to Nettuts+'s implementation which uploads files to S3 with full public access.

Using the Code

The source code provided includes the AWS SDK PHP (version 2011.01.14), but you can't simply unzip it, throw it on a web server, and make it run. Assuming you have PHP enabled, you still need to do the following things:

  1. Have an Amazon S3 account.
  2. Have a bucket called "bucket" (or change the code to look in a different bucket).
  3. Create a config.inc.php file with your own S3 credentials from the config-sample.inc.php that is included (keep your config.inc.php file in the same folder/directory).

At that point, you should be good to go!

The first part of the code in index.php simply uploads a file using a form:

PHP
$s3 = new AmazonS3();
$bucket = "bucket";

// check whether a form was submitted
if (isset($_POST['submit'])) {
    // retrieve post variables
    $file = $_FILES['file'];
    $filename = $file['name'];
    $tmpname = $file['tmp_name'];
    $contentType = $file['type'];

    // upload the file
    $fileResource = fopen($tmpname, 'r');
    try {
        $response = $s3->create_object($bucket, $filename, 
           array('fileUpload' => $fileResource, 'contentType' => $contentType));
        if ($response->isOK())
            echo "<strong>Upload of $filename succeeded.</strong>\n";
        else
            echo "<strong>Upload of $filename failed.</strong>\n";
    } catch (Exception $e) {
            echo 'Caught exception: ',  $e->getMessage(), "\n";
    }
}

Note that I've put it into a try/catch block because S3::create_object() can blow up (I've notice it do so when I've tried to upload files that are several megabytes).

The second part of index.php displays the files you have in the pre-designated bucket. It loops through the files in the bucket and checks if the file is an image file (a simplistic check of the file extension). If it is an image, it displays it, if not, it makes a hyperlink to it showing a document icon:

PHP
$response = $s3->list_objects($bucket);

$contents = $response->body->Contents;
foreach ($contents as $content) {
    $filename = $content->Key;
    echo "<p>$filename</p>\n";
    if (isImage($filename)) {
        echo "<img width='150' height='100' src='file." + 
             "php?bucket=$bucket&filename=$filename'/>\n";
    } else {
        echo "<a href='file.php?bucket=$bucket&filename=$filename'>" + 
             "<img width='50' height='50' src='document.png'/></a>\n";
    }
}

The hyperlink or the source of the image is gotten from the file.php file, which is very straightforward:

PHP
$bucket = $_GET['bucket'];
$filename = $_GET['filename'];

// Include the SDK
require_once 'sdk.class.php';

// Instantiate the class
$s3 = new AmazonS3();
$response = $s3->get_object($bucket, $filename);
$contentType = $response->header['_info']['content_type'];
header("Content-type: $contentType");
header("Content-Disposition: filename=$filename");
echo $response->body;

The only "magic" lies in the header directives which provide the content type and preserves the file name when downloading.

The only thing missing is more defensive code in both files that restricts its access. I'll leave that up to the reader as an exercise :-)

Points of Interest

At first, I was stupidly futzing around with PHP GD to make the images appear. However, there's no need for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
United States United States
Chuck is:
-Sole Proprietor/Consultant with PROTOTYPOS
-a Consulting Assistant Professor in the Stanford University Department of Civil and Environmental Engineering
-a licensed architect in the State of California
-a scratch golfer (yeah, right)

Comments and Discussions

 
GeneralMy vote of 5 Pin
Manoj Kumar Choubey23-Feb-12 19:37
professionalManoj Kumar Choubey23-Feb-12 19:37 
QuestionLarger Files Pin
Member 784860817-Apr-11 2:40
Member 784860817-Apr-11 2:40 
AnswerRe: Larger Files Pin
Chuck Han17-Apr-11 8:55
Chuck Han17-Apr-11 8:55 
Questiondisplay image directly without php proxy file? Pin
Zeilstar9-Mar-11 12:00
Zeilstar9-Mar-11 12:00 
AnswerRe: display image directly without php proxy file? Pin
Chuck Han9-Mar-11 13:27
Chuck Han9-Mar-11 13:27 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.