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)
- Download latest development version (0.5.x – recommended)
- Download old stable version (0.4.0 – 20th Jul 2009)
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:
- Amazon S3 documentation
How to Use Amazon S3 & PHP to Dynamically Store and Manage Files with Ease- Building a Small Business Backup System Using Amazon S3
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.
Just wanted to ping this post, make sure that development on this class wasn’t dead. Has the Amazon API simply stabilized?
Thank you very much!
EDIT: “Your comment looks like it could be spam.
Please try altering your input.”
Problem solved – my Mac didn’t allow the outbound call to S3 Server
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
Is there a way we can just list folders in a bucket? I am having a hard time figuring that out.
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
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
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 ?
S3 versioning please.
v0.4.0 is very old.
Finally needed to look into S3, and this class has saved me a lot of time. Thanks!
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.
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.
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.
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?
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.
@ian — that did it. Looks like I came to the site here about 40 seconds too early!
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
@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.
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?
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.
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?
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
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
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
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.
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
Thanks Boss Reron.
i have got more than 1000 errors here.
Now this works fine.
Again thank you.
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!
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.
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.
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.
Hi again
,
is it correct, this class doesn’t support creating/listing/updating/deleting streaming distributions, or am i missing something??
Thank you, Luk
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
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
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!
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)
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
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.
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
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
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?
laxmikant: Do you have write permissions in the bucket you’re trying to write to?
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
thanks buddy
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
how i can create sub folder plz help me
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!
@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.
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?
@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.