I've been trying to reduce my hosting costs lately, and I finally decided to test out Amazon S3. Their bandwidth and storage prices are very affordable, and unlike many hosts you only pay for what you use. What had previously kept me from using S3 was my inexperience with the REST and SOAP interfaces. Taking another look at S3, I found Geoff from Neurofuzzy has written an excellent PHP wrapper using S3's REST interface. I had two minor problems with the script, which I've fixed and incorporated into a slightly modified version. For reference purposes, these changes were turning DATE_RFC822 into DATE_RFC822_S3, and setting the $_debug flag to false.

Using Geoff's wrapper, I built a little PHP interface to manage buckets and files. It's still in an early state, but someone might benefit from it. If you want to incorporate S3 functionality into an existing web app, I'd use Geoff's wrapper. My s3ui is designed to be a standalone interface for adding/deleting buckets and objects.

UPDATE: The easiest way to begin immediately working with your S3 account is the Firefox S3Fox plugin, and you will want to use this plugin to upload large files, because Geoff's PHP wrapper does not stream the content to the S3 server.

Geoff's (modified) S3 Library
Todd's S3ui

In both of the linked files above, the first step is adding your key and secret key to the s3 library file. For more info on my s3ui, see the README file.

For those wanting to use Geoff's wrapper in their own scripts, I've included some small code snippets to show how easy it is. First you have to include the s3.php library:
include 's3.php';

Then you create a new s3 connection object:
$conn = new s3();

Buckets are like folders for your pictures. If you haven't created a bucket, you need to do so. The name has to be unique, so generic names are no good:
echo $conn->putBucket("myUniqueBucketName");

To make sure it was created correctly, we can list all of the buckets we own using the getBuckets() function. It will list the name and creation date of each bucket we own.
echo $conn->getBuckets();

If your bucket was created correctly, now we can add our files to the new bucket. Substitute $url for your own file (local or remote) and change "objectName" to whatever name you want to use to access the file. If you want your file to be readable by everyone, set the acl to public-read, otherwise you'll want to set it to private.
$objectData = file_get_contents($url);
$acl = "public-read";
echo $conn->putObject("objectName", $objectData, $bucketName, $acl);

If we used the "public-read" visibility and our object was added correctly, we can browse to see our object at:
http://s3.amazonaws.com/mybucket/myobject

We can also list all of the items within a specified bucket. If you examine the XML, you'll find that each object has a key. This is what we use to access our files.
echo $conn->getObjects($bucketName);

To use the files, you call getObject(). This will return whatever type of data you have stored, whether it is binary or plain text. The header you use will be dependent on the type of data you are serving up.
$objectName = "myObjectName";
$data = $conn->getObject($objectName, $bucketName);
$type = $conn->getResponseContentType();
header("Content-type: ".$type);
header("Content-disposition: attachment; filename=\"".$objectName."\"");
echo $data;

If you want to delete an object, you just have to specify the objectName and bucketName
$conn->deleteObject("objectName", $bucketName);