Click here to Skip to main content
Click here to Skip to main content

PHP AWS SDK (S3)

, 4 Feb 2011
Rate this:
Please Sign up or sign in to vote.
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:

$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:

$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:

$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 Smile | :)

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)

Share

About the Author

Chuck Han
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 Pinmembermanoj kumar choubey23-Feb-12 19:37 
QuestionLarger Files PinmemberMember 784860817-Apr-11 2:40 
AnswerRe: Larger Files PinmemberChuck Han17-Apr-11 8:55 
Questiondisplay image directly without php proxy file? PinmemberZeilstar9-Mar-11 12:00 
AnswerRe: display image directly without php proxy file? PinmemberChuck Han9-Mar-11 13:27 

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

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

| Advertise | Privacy | Mobile
Web01 | 2.8.140827.1 | Last Updated 4 Feb 2011
Article Copyright 2011 by Chuck Han
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid