View Source

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[{composition-setup}{composition-setup}]]></ac:plain-text-body></ac:macro>
<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[{zone-template-instance:ZFDEV:Zend Proposal Zone Template}

{zone-data:component-name}
Zend_Service_Amazon_S3
{zone-data}

{zone-data:proposer-list}
[Justin Plock|mailto:jplock@gmail.com]
[Alexander Veremyev|mailto:alexander.v@zend.com] (Zend liaison)
[Stanislav Malyshev|mailto:stas@zend.com]
{zone-data}

{zone-data:revision}
1.0 - 10 March 2008: Initial revision.
1.1 - 31 December 2008: Revised code committed into laboratory SVN
2.0 - 25 February 2009: Revised the API and finalized the laboratory implementation
{zone-data}

{zone-data:overview}
Zend_Service_Amazon_S3 is an implementation of the service API and PHP user-stream wrapper for Amazon's Simple Storage Service (S3)
{zone-data}

{zone-data:references}
* [Amazon S3 Developer's Guide|http://docs.amazonwebservices.com/AmazonS3/2006-03-01/]
{zone-data}

{zone-data:requirements}
* This component *will* implement the Amazon S3 API
* This component *will* use Zend_Http_Client to communicate with S3
* This component *will* provide the API to use Amazon S3 directly
* This component *will* implement a user-based stream wrapper for S3 (s3://)
* This component *will* allow using multiple S3 accounts
{zone-data}

{zone-data:dependencies}
* Zend_Http_Client
{zone-data}

{zone-data:operation}
This component will provide Amazon S3 API allowing to store and retrieve data from the Amazon S3 service.

Also, this component will be utilized using the stream_wrapper_register() PHP method to register a new user-based stream interface to S3. This allows the user to utilize existing fread(), fwrite(), fclose(), mkdir(), rmdir(), and stat() methods to directly interface with S3 buckets and objects.
{zone-data}

{zone-data:milestones}
* Milestone 1: \[DONE\] Design notes will be published here
* Milestone 2: \[DONE\] Working prototype checked into the laboratory supporting use cases
* Milestone 3: \[DONE\] Unit tests exist, work, and are checked into SVN.
* Milestone 4: \[DONE\] Initial documentation exists.
* Milestone 5: Proposal accepted and moved to incubator
* Milestone 6: The component is accepted as part of ZF core
{zone-data}

{zone-data:class-list}
* Zend_Service_Amazon_S3
* Zend_Service_Amazon_S3_Stream
{zone-data}

{zone-data:use-cases}
{deck:id=Use Cases}
{card:label=Use Case 1: Direct API}
{code}
require_once 'Zend/Service/Amazon/S3.php';

define('AWS_ACCESS_KEY', 'my-access-key');
define('AWS_SECRET_KEY', 'my-secret-key');

$s3 = new Zend_Service_Amazon_S3(AWS_ACCESS_KEY, AWS_SECRET_KEY);

$s3->createBucket("my-own-bucket");

$s3->putObject("my-own-bucket/myobject", "somedata");

echo $s3->getObject("my-own-bucket/myobject");
{code}
{card}
{card:label=Use Case 2: Streams API}
{code}
<?php
require_once 'Zend/Service/Amazon/S3.php';

define('AWS_ACCESS_KEY', 'my-access-key');
define('AWS_SECRET_KEY', 'my-secret-key');

$s3 = new Zend_Service_Amazon_S3(AWS_ACCESS_KEY, AWS_SECRET_KEY);

$s3->registerStreamWrapper("s3");

mkdir("s3://my-own-bucket");
file_put_contents("s3://my-own-bucket/testdata", "mydata");

echo file_get_contents("s3://my-own-bucket/testdata");
{code}
{card}
{card:label=Use Case 3: Streams API - more actions}
{code}
require_once 'Zend/Service/Amazon/S3.php';

define('AWS_ACCESS_KEY', 'my-access-key');
define('AWS_SECRET_KEY', 'my-secret-key');

$s3 = new Zend_Service_Amazon_S3(AWS_ACCESS_KEY, AWS_SECRET_KEY);

mkdir('s3://php-test');

$f = fopen('s3://php-test/file.txt', 'w');
for ($i = 0; $i <= 10000; $i++) {
fwrite($f, "Line #$i");
}
fclose($f);

$f = fopen('s3://php-test/file.txt', 'r');

$data = '';
while (!feof($f)) {
$data .= fread($f, 1024);
}
fclose($f);

echo '';
echo nl2br($data);
echo '';

$e = opendir('s3://');
while (($f = readdir($e)) !== false) {
echo "BUCKET: $f
";
}
closedir($e);

$stat = stat('s3://php-test/file.txt');
var_dump($stat);

$stat = stat('s3://php-test');
var_dump($stat);

unlink('s3://php-test/file.txt');
rmdir('s3://php-test');
{code}
{card}
{deck}
{zone-data}

{zone-data:skeletons}
{deck:id=Use Cases}
{card:label=Zend_Service_Amazon_S3}
{code}
/**
* Amazon S3 PHP connection class
*
* @category Zend
* @package Zend_Service
* @subpackage Amazon_S3
* @copyright Copyright (c) 2005-2008, Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Service_Amazon_S3 extends Zend_Service_Abstract
{
/**
* @var string Amazon Access Key
*/
protected static $default_accessKey = null;

/**
* @var string Amazon Secret Key
*/
protected static $default_secretKey = null;

/**
* Store for stream wrapper clients
*
* @var array
*/
protected static $_wrapperClients = array();

const S3_ENDPOINT = 'http://s3.amazonaws.com';

const S3_ACL_PRIVATE = 'private';
const S3_ACL_PUBLIC_READ = 'public-read';
const S3_ACL_PUBLIC_WRITE = 'public-read-write';
const S3_ACL_AUTH_READ = 'authenticated-read';

const S3_ACL_HEADER = 'x-amz-acl';
const S3_CONTENT_TYPE_HEADER = 'Content-Type';

/**
* @var string Amazon Secret Key
*/
protected $_secretKey;

/**
* @var string Amazon Access Key
*/
protected $_accessKey;

/**
* Set the keys to use when accessing S3.
*
* @param string $access_key
* @param string $secret_key
* @return void
*/
public static function setKeys($access_key, $secret_key)
{
}

/**
* Create Amazon S3 client.
*
* @param string $access_key
* @param string $secret_key
* @return void
*/
public function __construct($access_key=null, $secret_key=null) {
}

/**
* Add a new bucket
*
* @param string $bucket
* @return boolean
*/
public function createBucket($bucket)
{
}

/**
* Checks if a given bucket name is available
*
* @param string $bucket
* @return boolean
*/
public function isBucketAvailable($bucket)
{
}

/**
* Checks if a given object exists
*
* @param string $object
* @return boolean
*/
public function isObjectAvailable($object)
{
}

/**
* Remove a given bucket. All objects in the bucket must be removed prior
* to removing the bucket.
*
* @param string $bucket
* @return boolean
*/
public function removeBucket($bucket)
{
}

/**
* Get metadata information for a given object
*
* @param string $object
* @return array
*/
public function getInfo($object)
{
}

/**
* List the S3 buckets
*
* @return array|false
*/
public function getBuckets()
{
}

/**
* Remove all objects in the bucket.
*
* @param string $bucket
* @return boolean
*/
public function cleanBucket($bucket) {
}

/**
* List the objects in a bucket.
*
* Provides the list of object keys that are contained in the bucket.
*
* @param string $bucket
* @return array|false
*/
public function getObjectsByBucket($bucket)
{
}

/**
* Get an object
*
* @param string $object
* @return string|false
*/
public function getObject($object)
{
}

/**
* Upload an object by a PHP string
*
* @param string $object Object name
* @param string $data Object data
* @param [array] $meta Metadata
* @return boolean
*/
public function putObject($object, $data, $meta = null)
{
}

/**
* Put file to S3 as object
*
* @param string $path File name
* @param string $object Object name
* @param [array] $meta Metadata
* @return boolean
*/
public function putFile($path, $object, $meta=null)
{
}

/**
* Remove a given object
*
* @param string $object
* @return boolean
*/
public function removeObject($object)
{
}

/**
* Make a request to Amazon S3
*
* TODO: support bucket.s3.amazon.com style
*
* @param string $method
* @param string $path
* @param array $params
* @param array $headers
* @param string $data
* @return Zend_Http_Response
*/
public function _makeRequest($method, $path='', $params=null, $headers=array(), $data=null)
{
}

/**
* Register this object as stream wrapper
*
* @param string $name
*/
public function registerStreamWrapper($name="s3")
{
}

/**
* Unregister this object as stream wrapper
*
* @param string $name
*/
public function unregisterStreamWrapper($name="s3")
{
}
}
{code}
{card}
{card:label=Zend_Service_Amazon_S3_Stream}
{code}
class Zend_Service_Amazon_S3_Stream
{
/**
* @var boolean Write the buffer on fflush()?
*/
private $_writeBuffer = false;

/**
* @var integer Current read/write position
*/
private $_position = 0;

/**
* @var integer Total size of the object as returned by S3 (Content-length)
*/
private $_objectSize = 0;

/**
* @var string File name to interact with
*/
private $_objectName = null;

/**
* @var string Current read/write buffer
*/
private $_objectBuffer = null;

/**
* @var array Available buckets
*/
private $_bucketList = array();

private $_s3;

/**
* Open the stream
*
* @param string $path
* @param string $mode
* @param integer $options
* @param string $opened_path
* @return boolean
*/
public function stream_open($path, $mode, $options, $opened_path)
{
}

/**
* Close the stream
*
* @return void
*/
public function stream_close()
{
}

/**
* Read from the stream
*
* @param integer $count
* @return string
*/
public function stream_read($count)
{
}

/**
* Write to the stream
*
* @param string $data
* @return integer
*/
public function stream_write($data)
{
}

/**
* End of the stream?
*
* @return boolean
*/
public function stream_eof()
{
}

/**
* What is the current read/write position of the stream
*
* @return integer
*/
public function stream_tell()
{
}

/**
* Update the read/write position of the stream
*
* @param integer $offset
* @param integer $whence
* @return boolean
*/
public function stream_seek($offset, $whence)
{
}

/**
* Flush current cached stream data to storage
*
* @return boolean
*/
public function stream_flush()
{
}

/**
* Returns data array of stream variables
*
* @return array
*/
public function stream_stat()
{
}

/**
* Attempt to delete the item
*
* @param string $path
* @return boolean
*/
public function unlink($path)
{
}

/**
* Attempt to rename the item
*
* @param string $path_from
* @param string $path_to
* @return boolean False
*/
public function rename($path_from, $path_to)
{
}

/**
* Create a new directory
*
* @param string $path
* @param integer $mode
* @param integer $options
* @return boolean
*/
public function mkdir($path, $mode, $options)
{
}

/**
* Remove a directory
*
* @param string $path
* @param integer $options
* @return boolean
*/
public function rmdir($path, $options)
{
}

/**
* Attempt to open a directory
*
* @param string $path
* @param integer $options
* @return boolean
*/
public function dir_opendir($path, $options)
{
}

/**
* Return array of URL variables
*
* @param string $path
* @param integer $flags
* @return array
*/
public function url_stat($path, $flags)
{
}

/**
* Return the next filename in the directory
*
* @return string
*/
public function dir_readdir()
{
}

/**
* Reset the directory pointer
*
* @return boolean True
*/
public function dir_rewinddir()
{
}

/**
* Close a directory
*
* @return boolean True
*/
public function dir_closedir()
{
}
}
{code}
{card}
{deck}
{zone-data}

{zone-template-instance}]]></ac:plain-text-body></ac:macro>