Amazon S3 PHP Class

This class is a standalone Amazon S3 REST implementation for PHP 5.2.x (using CURL), that supports large file uploads and doesn’t require PEAR.

Download source: (view changelog)

Usage: See the class documentation and example.php in the source distribution.

Known Issues:

  • Files larger than 2GB are not supported on 32 bit systems due to PHP’s signed integer problem
  • SSL is enabled by default and can cause problems with large files. If you don’t need SSL, disable it with S3::$useSSL = false;

More Information:

NOTE ON FOLDERS: Amazon S3 does not support folders.  Clients like S3Fox create specific files that are displayed as folders.  Just use slash paths for your object names (foo/bar.txt) and (foo/) as your prefix when listing contents.

Amazon S3™ is a trademark of Amazon.com, Inc. or its affiliates.

This entry was posted in Uncategorized and tagged , . Bookmark the permalink.

303 Responses to Amazon S3 PHP Class

  1. Frank Koehl says:

    Just wanted to ping this post, make sure that development on this class wasn’t dead. Has the Amazon API simply stabilized?

  2. Terenn says:

    Thank you very much!

    EDIT: “Your comment looks like it could be spam.
    Please try altering your input.”

  3. Andrew says:

    Problem solved – my Mac didn’t allow the outbound call to S3 Server :)

  4. Andrew says:

    Hi there,
    great class – however I can’t test it and I think it is a problem that I ran my server localy via MAMP PRO and a special port on my Mac. The class creation doesn’t work and the page loads endless without any error message.

    Can anyone share a tip what this could be!

    Thanks a lot for any help!
    Andrew

  5. John H. says:

    Is there a way we can just list folders in a bucket? I am having a hard time figuring that out.

  6. RJ says:

    Is there a way by which i can generate url for files to be downloaded directly…..currently the url generated through getAuthenticatedUrl opens the image in d clients browser…i want it to be downloaded…..

    Thanks

  7. Chris Dean says:

    Just seen this and admit I’ve not read anything about it fully yet, but I was thinking of building a kohana module around cloudfusion (http://getcloudfusion.com/) to do something similar…

    Not sure if it’d be of benefit to you to investigate cloudfusion integration for this project?

    Chris

  8. pawan kumar says:

    Hello Sir

    This script work fine for small files. but when i upload large file e.g. 80MB, The file is moved to s3 ok but PHP gives up waiting to and so does not execute the rest of the code.Can any one provide me the solution for this ?

  9. Gnome says:

    S3 versioning please.
    v0.4.0 is very old.

  10. Todd says:

    Finally needed to look into S3, and this class has saved me a lot of time. Thanks!

  11. Heron says:

    mconnors,

    That sounds like something you should contact the S3 team about (try the forums at aws.amazon.com). I don’t know why that might be happening.

  12. Heron says:

    rvera10,

    If you want the file on S3 to be the only thing passed to the user, you could simply redirect them to the URL of the object on S3 (perhaps using an authenticated URL if it’s a private file).

    If you want the file embedded in other output, though, well it depends. If it’s an image, then again you can use the URL straight to the S3 object as the image’s URL in the HTML output. If it’s a text file, then S3 isn’t really a good place to store it.

  13. rvera10 says:

    I’m new to php and was wondering if I could get some help in how to get a file from s3 back to the browser. I believe I need to use the getObject(‘bucketname’, ‘uri’) function. But I do not want to save it to the server and then open it open to flush it out to the browser. I would like to take the return Object or Reference to what’s being returned in the getObject and probably use something like fpassthru(). But not sure if this is the correct way to do this.

    Any help will be greatly appreciated.

    Thanks in advance.

  14. mconnors says:

    I could really use some help. After having a massive directory tree of a million files uploaded to a bucket with AWS import, I can’t see any folders with anything other than cyberduck or s3fox. All other attempts won’t show the folders including this class. Any ideas?

  15. a.yamanoi says:

    Thanks for a great class!

    In the copyObject(…) function,

    -$rest->setAmzHeader(‘x-amz-copy-source’, sprintf(‘/%s/%s’, $srcBucket, $srcUri));
    +$rest->setAmzHeader(‘x-amz-copy-source’, sprintf(‘/%s/%s’, $srcBucket, rawurlencode($srcUri)));

    I use above code for multibyte filenames.

  16. Andrew Slater says:

    @ian — that did it. Looks like I came to the site here about 40 seconds too early!

  17. Andrew Slater says:

    Same SSL3 etc problem — this is new as of yesterday for me. Nothing changed on my end, so I’m guessing that maybe something changed on Amazon’s end that we need to change in the code?

    Andrew

  18. ian says:

    @Scott:

    For a workaround, edit the S3 class, and go to ~ line 1222.

    You have to disable Peer Verification (replace 1, with 0), in this line:

    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 1);

    Hope this helps.

  19. Scott says:

    I seem to be bumping into the same SSL problem everyone else. I’m running tests on a local XAMPP install- I can upload files just fine and verified them via S3Fox. However, any attempt to list buckets or put buckets or do anything else drops the following error:

    Warning: S3::listBuckets(): [60] SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed in C:\xampp\htdocs\S3Native\S3.php on line 91

    I tried setting $useSSL=false in the constructor, but it didn’t change anything. Ideas?

  20. Heron says:

    chandrav,

    There’s no such thing as a ‘folder’ or ‘directory’ in S3 buckets. If you want to simulate directories, you need to prefix your object names with the virtual directory name. For example, suppose you want to pretend there’s a folder named “test”. What you need to do is to name all of the objects that go in that folder such that they begin with “test/”. So if “foobar.html” goes in the “test” folder, you’d put it in your S3 bucket with the name “test/foobar.html”.

    Again, S3 has no concept of folders or directories. S3Fox and tools like it simply pretend there are folders, based on filename prefixes.

  21. chandrav says:

    if the bucket name has “/” in it it does not create recursive directory.

    say you want to create a director test2 in test.

    $handle->putBucket(“test/test2″, ‘public-read’);

    this gives me an error.

    Is there a way to do this?

  22. Loz says:

    Hi Heron

    Thanks for replying.

    yes, this is the code I used at the top of my php page.

    XXXX = my amazon key stuff.

    <?php
    $S3AWSID=’XXXXXXXXXX’;
    $S3AWSSECRET=’XXXXXX’;
    require_once ‘S3.php’;
    $s3 = new S3(“$S3AWSID”, “$S3AWSSECRET”);
    ?>

    This is the ebook I followed.

    http://www.ask-me-about.com/Securing-Files-on-S3.pdf

    The S3.php page is in the same directory as that of the php file that contains that information at the top of the page.

    Thanks for your email, i will send you a note shortly.

    Cheers

    Loz

  23. jbq says:

    OK I understand now, I have to call putObject() with empty bucket name and rather have the bucket name included in the URI. This way I don’t come across the problem and don’t get signature mismatch. There must be a bug somewhere in the S3 class when bucket parameter is defined and “Host: mybucket.s3.amazonaws.com” is used

  24. jbq says:

    I created a bucket with s3cmd with both lower and uppercase chars, and when using your class I kept getting the following error until I removed the strtolower($bucket) call in the S3Request constructor: S3::putObject(): [NoSuchBucket] The specified bucket does not exist

  25. Heron says:

    Loz: did you require(‘S3.php’); at the top of your PHP code? Did you properly initialize the $s3 variable by creating an instance of the S3 class?

    If you’re trying to use it statically, you need to set the S3 access key and secret key with the appropriate static method, and access it via S3::methodname() rather than with a variable.

    I can give you more help, but you’ll have to show more of your code than just one line. Feel free to e-mail me at heron@xnapid.com if you need more help.

  26. Loz says:

    I cant get this to work :(

    <?php echo $s3‐>getAuthenticatedURL(“evp-4b69f2e172842-e7015e5af93fdd8e3157715cb3c112db”, “video.mp4″, 120); ?>

    spits out this error

    Fatal error: Call to undefined function getAuthenticatedURL()

    any help appreciated.

    I used the firefox S3 plugin, and set EVERYONE to NO, and authenticated users to YES

    I dont understand whats going on here :(

  27. Arifcsecu(Bangladesh) says:

    Thanks Boss Reron.
    i have got more than 1000 errors here.

    Now this works fine.

    Again thank you.

  28. Liam says:

    I have just started using your S3 class and when I try to upload a file I recieve the following error: “S3::inputFile(): Unable to open input file:”

    I am completely lost to what is causing this error, any help would be much appreciated!

    Thanks!

  29. Heron says:

    Hi Arifcsecu,

    Amazon S3 uses time to verify signatures; if the sigature says “10:00 am GMT” but it’s actually 5:00pm GMT Amazon will reject the request.

    Make sure the computer running the script has its time set properly – either set it to the correct GMT time, or set the time and the timezone properly for its location.

  30. Arifcsecu(Bangladesh) says:

    when i sent
    S3::$useSSL = false;
    $s3->putBucket($bucket,S3::ACL_PRIVATE);
    i got the error.

    Warning: S3::putBucket(abc, private, ): [RequestTimeTooSkewed] The difference between the request time and the current time is too large. in C:\xampp\htdocs\np\S3.php on line 226

    Warning: S3::putObject(): [RequestTimeTooSkewed] The difference between the request time and the current time is too large. in C:\xampp\htdocs\np\S3.php on line 358
    Something went wrong while uploading your file… sorry.

  31. Arifcsecu(Bangladesh) says:

    i got this error. i don’t understand why this happen?

    Warning: S3::putObject(): [60] SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed in C:\xampp\htdocs\S3.php on line 358
    Something went wrong while uploading your file… sorry.

  32. Luk says:

    Hi again :) ,

    is it correct, this class doesn’t support creating/listing/updating/deleting streaming distributions, or am i missing something??

    Thank you, Luk

  33. Luk says:

    Hi,

    I just started to use this class, and I am having problems with example-cloudfront.php.

    Warning: S3::listDistributions(): [60] SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed in S3.php on line 935

    Even when I try to change the resource to 2009-12-01/distribution, the warning is the same. When I try to set $useSSL to false, I cannot obviously connect to the host… Besides, I can use listBuckets() only with disabled SSL, so I am not really sure what is wrong, or what could help.

    Any ideas?
    Thanks,
    Luk

  34. Hugo says:

    Is there a way to append a string to the name of the file while uploading it to the S3 server? ie: file to upload using the html form = my_file.txt once uploaded would become 1_my_file.txt

    Thank you

  35. Yousef says:

    Khanh, we were having the same problem so we tried all the usual PHP changes (post_max_size, upload_max_filesize, memory_limit, max_execution_time). None of them helped… In the end we figured out it was the Apache timeout stopping the script completing. Now it’s working fine for 50MB files. We’ll be trying larger ones later.

    Great class by the way!

  36. Khanh says:

    Thank you so much for such a useful class. I was able to use this class as expected to upload files to S3. I am running into an issue with any files larger then 10mb. I’ve changed the upload size in php to 20mb and still no luck. There are no errors being kicked back either.

    $s3->putObjectFile($fileTempName, $dest_bucket, $fileName, S3::ACL_PUBLIC_READ)

  37. Heron says:

    ilija:

    This S3 class only allows client->server->Amazon S3 transfers. If you want client->Amazon S3 transfers, you’ll want to set up an upload form using POST.

    Read this example:

    http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1618

    Hope that helps.

    - Heron

  38. ilija says:

    Hi,

    I am little bit confused with REST api and how to use it.
    My concern is if using this script file will get downloaded
    to server first before going to a client browser or is it a way to download file from s3 to client browser directly.
    I am looking for a way to skip double bandwidth (from s3 to serevr->server to client).

    Thank you.

    I.

  39. Heron says:

    Ian,

    getRequest actually retrieves responses in two different places. Right above the do-while loop is an if statement that checks if the first response was truncated, and if so, it enters the loop, where it checks for further responses.

    Does that make sense?

    - Heron

  40. Ian Anderson says:

    Ah – I think I see the magic that does it, sorry

    do { … } while ($response !== false && (string)$response->body->IsTruncated == ‘true’);

    When I echo out a marker at the top of the loop it only gets echoed once though, and it should get echoed twice – weird. But it works brilliantly – thanks once again, Don

  41. Ian Anderson says:

    I have a complaint to make – it’s working too well and I don’t understand why :)

    When I call getBucket(), as I understand things, it should only receive 1000 objects from Amazon and the truncated property should be set to true so that I know to call it again

    But I’m receiving all the objects in my bucket anyway – about 1400 – and the truncated property is still set to true

    Does anyone else get this?

  42. Heron says:

    laxmikant: Do you have write permissions in the bucket you’re trying to write to?

  43. laxmikant says:

    in one bucket i m not able to uplaod the files by same code i m able to upload the file in another bucket. what’s reason any one can help me

    Any ideas? Thanks

  44. laxmikant says:

    thanks buddy

  45. Corey Sewell says:

    Hi, I found a faster way to get sizes of buckets. I ended up making a class for downloading and parsing the reports you get from the AWS portal.
    Its related to your class so thought I would share. You can find out more here:
    http://amazontools.blogspot.com/2009/12/first-alpha-release.html
    Cheers

  46. laxmikant says:

    how i can create sub folder plz help me

  47. Kirby says:

    Hi-

    I am creating a jpg bytearray in actionscript, passing it to php, and attempting to upload to the S3 using putObject. Unfortunately, I get stuck with an error that says “MalFormed XML…” I tried looking at the other threads but they weren’t clear on their answers. Here is my code:

    //it passings a jpg bytearray name “jpgData”

    $s3 = new S3($awsAccessKey, $awsSecretKey);

    $filename = “test.jpg”;
    $input = array();
    $input["data"] = $jpgData->data;
    $input["type"] = “image/jpg”;

    return $s3->putObject($input, “storage.kirbysbeard.com”, $fileName, “public-read”);

    Any ideas? Thanks and your class is awesome!

  48. Don says:

    @cjsewell: Unfortunately that’s the only way. Better way might be to maintain a local SQL based listing for buckets and use that to calculate sizes.

  49. cjsewell says:

    Hi there, I am trying to get the total size of a bucket, so far the only way I can do it is by looping through the response of getBucket.
    This works, but is extremely slow, especially for large buckets.
    Is there any better, faster way?

  50. Don says:

    @Para: There is no function to do what you need. See the logging documentation. The class lets you enable/disable logging. You would still need to download those logs and parse them accordingly.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>