My favorites | Sign in
Project Logo
                
Search
for
Updated Nov 15, 2008 by tylerhall
Labels: Phase-Implementation, Deprecated
S3Class  
Programmer's reference for class.s3.php (Simple Storage Service).

class.s3.php

class.s3.php allows you to interact with Amazon's Simple Storage Service (S3). You can add/remove buckets and keys and query information about them as well. Curl is used to enable working with large files.

Usage

The following code creates a new S3 object and displays a list of available buckets.

$s3 = new S3("Your Amazon Key", "Your Secret Amazon Key");
$buckets = $s3->getBuckets();
foreach($buckets as $bucket)
  echo $bucket . "<br/>";

Members

$key

Contains your Amazon key.

$secret

Contains your Amazon secret key.

$server

Fully-qualified URL to Amazon's S3 server. Defaults to http://s3.amazonaws.com. Most likely, this won't ever need to be changed.

$pathToCurl

In order to handle large files efficiently (without loading them into memory), we use curl directly at the system shell level. $_pathToCurl needs to point to curl's location on your system. In most cases, you can simply set this to "curl" as the command in typically available in your path. If that doesn't work, you can locate curl on your system by running which curl or locate curl at a command prompt.

Future versions will attempt to auto-detect curl's location if the one you specify is not valid (or executable).

$hasher

Instance of Crypt_HMAC() used to generate the sha1 request signature Amazon requires.

$date

Date of the current request.

$error

String containing an error message from Amazon if an error occurred.

Methods

construct($key, $secret)

The S3 constructor initializes $this->_hasher using Amazon key and secret key you supply.

base64($str)

Returns the base-64 encoded version of string $str.

bucketExists($bucket)

Returns true if $bucket is one of your available buckets. If false is returned, the bucket may potentially exist for another user.

createBucket($bucket)

Attempts to create $bucket as a new bucket in your account. Returns true on success. If not successful, false is returned and $this->error is set with the error message received from Amazon.

deleteBucket($bucket)

Attempts to delete the bucket named $bucket from your account. Returns true on success. If not successful, false is returned and $this->error is set with the error message received from Amazon.

Note: non-empty buckets cannot be deleted. This is a restriction (a good one) of Amazon.

deleteObject($bucket, $object)

Attempts to delete the object named $object in bucket $bucket. Returns true on success. False if the object could not be deleted.

directorySize($bucket, $prefix)

Returns the size, in bytes, of all the keys in bucket $bucket with prefix $prefix.

downloadObject($bucket, $object, $saveTo)

Downloads the object named $object from bucket $bucket and saves on the filesystem as $saveTo.

getBucketContents($bucket, $prefix, $delim, $marker)

Returns an array containing the contents of bucket $bucket. Please see the Amazon reference for an explanation of how $prefix, $delim, and $marker affect the results.

getBuckets()

Returns an array containing the buckets accessible to your account.

getObject($bucket, $object)

Returns the contents of the object $object in bucket $bucket.

Note: since this loads the contents into memory, consider using downloadObject() for large files.

getObjectHead($bucket, $object)

Returns the HTTP header info for object $object in bucket $bucket.

getObjectInfo($bucket, $object)

Returns Amazon's meta information about object $object in bucket $bucket.

isOk($result)

Searches the result of the current request for an error message. Returns true if none found. Otherwise, returns false and stores the error message in $this->_error.

objectExists($bucket, $object)

Returns true if object $object in bucket $bucket exists. False if it does not exist.

putObject($bucket, $object, $filename, $public, $disposition)

Stores the file $filename into bucket $bucket as object $object. If $public is true, the new object will be publicly accessible via the web at http://s3.amazonaws.com/$bucket/$object. If $disposition is set, the object will be stored with a special header to make the file download as an attachment named $disposition. This is useful if you want the file to have a different filename than its object name.

sendRequest($req, $params)

Sends the request specified by the array $req along with any additional params listed in the array $params.

Note: items in $req are sent as arguments to curl, while items in $params are sent in the query string.

signature($req)

Calculates a request signature using the algorithm specified by Amazon and the items in $req.

sortKeys($keys, $first)

Sorts the keys listed in $keys. If $first is null it sorts the keys alphabetically. If $first is "key", keys are sorted alphabetically followed by prefixes. If $first is "prefix", prefixes are sorted first then the keys. This is useful if you want to list your getBucketContents() results in a filesytem format. You can have files and directories intermixed (OS X style) or directories listed first (Windows style).


Comment by d3designs, Aug 13, 2007

It may be a good idea to add an additional function for query based auth. Here is one I made:

function createURL($bucket, $object, $time) {
$key = $this->key; $secret = $this->secret; $server = $this->server;

$expires = time() + $time;

$str = "GET\n\n\n" . $expires . "\n" . '/' . $bucket . '/' . $object;
$sha1 = $this->hasher($str); $sig = $this->base64($sha1); $sig = rawurlencode(trim($sig));

$url = $server . '/' . $bucket . '/' . $object . '?AWSAccessKeyId=' . $key . '&Expires=' . $expires . '&Signature=' . $sig;

return $url;
}

Comment by edaina, Sep 21, 2007

where can i download this class?

Comment by juangiordana, Oct 06, 2007

If I use:

"$PATH"

for $disposition on the putObject method, when I download the file I get:

__usr_local_bin__usr_local_sbin__bin__sbin__usr_bin__usr_sbin__usr_X11R6_bin_

wich is a BIG security violation.

Should my application handle this or should this be part of the class?

I'm new in OOP. Thanks

Comment by juangiordana, Oct 06, 2007

Also

{`echo hello`}

I'm interested on participating on this project.

Comment by juangiordana, Oct 06, 2007

Here is a quick solution I did to fix this problem:

	function sendRequest($req, $params = null)
	{
		if(isset($req['resource']))
		{
			$req['resource'] = urlencode($req['resource']);
			$req['resource'] = str_replace("%2F", "/", $req['resource']);
		}

		$sig = $this->signature($req);

		$args = array();
		$args[] = array("-H", "Date: " . $this->_date);
		$args[] = array("-H", "Authorization: AWS {$this->_key}:$sig");

		if(isset($req['acl'])) $args[] = array('-H', 'x-amz-acl: ' . $req['acl']);
		if(isset($req['type'])) $args[] = array('-H', 'Content-Type: ' . $req['type']);
		if(isset($req['md5'])) $args[] = array('-H', 'Content-Md5: ' . $req['md5']);
		if(isset($req['disposition'])) $args[] = array('-H', 'Content-Disposition: attachment; filename="' . $req['disposition'] . '"');
		if(isset($req['upload'])) $args[] = array('-T', $req['upload']);

		if(is_array($req['headers']))
			foreach($req['headers'] as $key => $val)
				$args[] = array('-H', "$key: $val");

		if(strtolower($req['verb']) != "head")
			$args[] = array("-X", $req['verb']);

		$curl = $this->_pathToCurl . " -s ";
		foreach($args as $arg)
		{
			list($key, $val) = $arg;
			$curl .= $key . ' ' . escapeshellarg($val) . ' ';
		}

		$curl .= '"' . $this->_server . $req['resource'];

		if(is_array($params))
		{
			$curl .= "?";
			foreach($params as $key => $val)
				$curl .= "$key=" . urlencode($val) . "&";
		}

		$curl .= '"';

		if(strtolower($req['verb']) == "head")
			$curl .= " -I ";

		if(isset($req['download'])) $curl .= ' -o "' . $req['download'] . '"';

		return `$curl`;
	}

Basically I used single quotes to set the values of the $args array since variables within singles quotes are not parsed by PHP (see variable parsing), and escapeshellarg to set the arguments for the curl comand.

Comment by the.mutatron, Oct 25, 2007

Amazon AWS, your links are broken. There's nowhere to go to download this class, or any other php files as far as I can tell.

Comment by juangiordana, Nov 02, 2007

http://php-aws.googlecode.com/svn/trunk/class.s3.php

The links aren't broken. You should look better ;) You should go to Source -> Subversion repository -> trunk -> class.s3.php

Comment by gil.megidish, Dec 02, 2007

You might want to add $curl .= " -m 60 " and limit your curl down to 60 seconds.

It happened several times already that curl never returned (not even after 12 hours.)I'm uploading tens of thousands of files a day, so I have better chances of this happening :)

Comment by drbigfresh, Feb 03, 2008

How can I create a multi-tier bucket? I am trying to mirror my local file system on a server, and would love to be able to create buckets to mimic something like this:

'/assets/images/icons/'

Anyone have any idea?

Comment by gagnon.francois, Feb 26, 2008

Name your object as the whole path. For instance: object name is: '/assets/images/icons/foo.gif'

Amazon as a max of 100 buckets anyway, so you could not mimic your file system

Comment by drbigfresh, Apr 04, 2008

Is there anyway to get debugging info? I'm having some problems and can't seem to trace the source of the error....

Comment by naineshsolanki, Apr 30, 2008

is there a way to copy an object without downloading it? i found this http://doc.s3.amazonaws.com/proposals/copy.html but am not sure if amazon has this functionality enabled yet

Comment by andrew.betts, Jul 30, 2008

I have extensively revised this class to address issues 11 and 19, and to make the following changes:

Tidying of sendRequest and signature to make them more consistent Some removal of redundant code Addition of getBucketACL() method to retrieve copy of access control policy Allow objects to be created with any ACP, not just public-read Allow buckets to be created with EU Location constraint Validation of location and ACP parameters Modified getLocation() to remove hack and use new standardised method for query string parameters.

Tyler - if you're interested in using it, let me know.

Comment by cokegen, Aug 19, 2008

As gil.megidish said, you better add -m 60 to $curl or the number of seconds you consider right for your application to prevent curl to hang indefinitely. It happened to me several times and curl not returning was in fact breaking my application.


Sign in to add a comment
Hosted by Google Code