Windows Azure is the name for Microsoft’s Software + Services platform, an operating system in the cloud providing services for hosting, management, scalable storage with support for simple blobs, tables, and queues, as well as a management infrastructure for provisioning and geo-distribution of cloud-based services, and a development platform for the Azure Services layer.
There are two development scenario's when working with Windows Azure.
You can develop your application using
Zend_Service_WindowsAzure and the Windows Azure SDK,
which provides a local developent environment of the services provided by
Windows Azure's cloud infrastructure.
You can develop your application using
Zend_Service_WindowsAzure, working directly with the
Windows Azure cloud infrastructure.
The first case requires you to install the Windows Azure SDK on your development machine. It is currently only available for Windows environments; progress is being made on a Java-based version of the SDK which can run on any platform.
The latter case requires you to have an account at Azure.com.
The Zend_Service_WindowsAzure class provides the PHP wrapper to
the Windows Azure REST interface. Please consult the REST
documentation for detailed description of the service. You will need to be
familiar with basic concepts in order to use this service.
Zend_Service_WindowsAzure provides the following functionality:
PHP classes for Windows Azure Blobs, Tables and Queues (for CRUD operations)
Helper Classes for HTTP transport, AuthN/AuthZ, REST and Error Management
Manageability, Instrumentation and Logging support
Zend_Service_WindowsAzure provides access to Windows Azure's
storage, computation and management interfaces by abstracting the REST/XML interface
Windows Azure provides into a simple PHP API.
An application built using Zend_Service_WindowsAzure can access
Windows Azure's features, no matter if it is hosted on the Windows Azure platform or on
an in-premise web server.
Blob Storage stores sets of binary data. Blob storage offers the following three resources: the storage account, containers, and blobs. Within your storage account, containers provide a way to organize sets of blobs within your storage account.
Blob Storage is offered by Windows Azure as a REST API which is
wrapped by the Zend_Service_WindowsAzure_Storage_Blob class in
order to provide a native PHP interface to the storage account.
This topic lists some examples of using the
Zend_Service_WindowsAzure_Storage_Blob class. Other features are
available in the download package, as well as a detailed API documentation of those
features.
Using the following code, a blob storage container can be created on development storage.
Example 60.174. Creating a storage container
$storageClient = new Zend_Service_WindowsAzure_Storage_Blob();
$result = $storageClient->createContainer('testcontainer');
echo 'Container name is: ' . $result->Name;
Using the following code, a blob storage container can be removed from development storage.
Example 60.175. Deleting a storage container
$storageClient = new Zend_Service_WindowsAzure_Storage_Blob();
$storageClient->deleteContainer('testcontainer');
Using the following code, a blob can be uploaded to a blob storage container on development storage. Note that the container has already been created before.
Example 60.176. Storing a blob
$storageClient = new Zend_Service_WindowsAzure_Storage_Blob();
// upload /home/maarten/example.txt to Azure
$result = $storageClient->putBlob(
'testcontainer', 'example.txt', '/home/maarten/example.txt'
);
echo 'Blob name is: ' . $result->Name;
Using the following code, a blob can be copied from inside the storage account. The advantage of using this method is that the copy operation occurs in the Azure cloud and does not involve downloading the blob. Note that the container has already been created before.
Example 60.177. Copying a blob
$storageClient = new Zend_Service_WindowsAzure_Storage_Blob();
// copy example.txt to example2.txt
$result = $storageClient->copyBlob(
'testcontainer', 'example.txt', 'testcontainer', 'example2.txt'
);
echo 'Copied blob name is: ' . $result->Name;
Using the following code, a blob can be downloaded from a blob storage container on development storage. Note that the container has already been created before and a blob has been uploaded.
Example 60.178. Downloading a blob
$storageClient = new Zend_Service_WindowsAzure_Storage_Blob();
// download file to /home/maarten/example.txt
$storageClient->getBlob(
'testcontainer', 'example.txt', '/home/maarten/example.txt'
);
By default, blob storage containers on Windows Azure are protected from public viewing. If any user on the Internet should have access to a blob container, its ACL can be set to public. Note that this applies to a complete container and not to a single blob!
Using the following code, blob storage container ACL can be set on development storage. Note that the container has already been created before.
Example 60.179. Making a blob publicly available
$storageClient = new Zend_Service_WindowsAzure_Storage_Blob();
// make container publicly available
$storageClient->setContainerAcl('testcontainer', Zend_Service_WindowsAzure_Storage_Blob::ACL_PUBLIC);
Windows Azure Blob Storage provides support to work with a "root container".
This means that a blob can be stored in the root of your storage account,
i.e. http://myaccount.blob.core.windows.net/somefile.txt.
In order to work with the root container, it should first be created using the
createContainer() method, naming the container
$root. All other operations on the root container should be issued
with the container name set to $root.
The Windows Azure SDK for PHP provides support for registering a blob storage
client as a PHP file stream wrapper. The blob storage stream wrapper provides
support for using regular file operations on Windows Azure Blob Storage.
For example, one can open a file from Windows Azure Blob Storage with
the fopen() function:
Example 60.180. Example usage of blob storage stream wrapper
$fileHandle = fopen('azure://mycontainer/myfile.txt', 'r');
// ...
fclose($fileHandle);
In order to do this, the Windows Azure SDK for PHP blob storage client
must be registered as a stream wrapper. This can be done by calling the
registerStreamWrapper() method:
Example 60.181. Registering the blob storage stream wrapper
$storageClient = new Zend_Service_WindowsAzure_Storage_Blob();
$storageClient->registerStreamWrapper(); // registers azure:// on this storage client
// or:
$storageClient->registerStreamWrapper('blob://'); // regiters blob:// on this storage client
To unregister the stream wrapper, the unregisterStreamWrapper()
method can be used.
Windows Azure Bob Storage provides a feature called "Shared Access Signatures". By default, there is only one level of authorization possible in Windows Azure Blob Storage: either a container is private or it is public. Shared Access Signatures provide a more granular method of authorization: read, write, delete and list permissions can be assigned on a container or a blob and given to a specific client using an URL-based model.
An example would be the following signature:
http://phpstorage.blob.core.windows.net/phpazuretestshared1?st=2009-08-17T09%3A06%3A17Z&se=2009-08-17T09%3A56%3A17Z&sr=c&sp=w&sig=hscQ7Su1nqd91OfMTwTkxabhJSaspx%2BD%2Fz8UqZAgn9s%3D
The above signature gives write access to the "phpazuretestshared1" container of the "phpstorage" account.
When you are the owner of a Windows Azure Bob Storage account, you can create and
distribute a shared access key for any type of resource in your account. To do this,
the generateSharedAccessUrl() method of the
Zend_Service_WindowsAzure_Storage_Blob storage client can be
used.
The following example code will generate a Shared Access Signature for write access in a container named "container1", within a timeframe of 3000 seconds.
Example 60.182. Generating a Shared Access Signature for a container
$storageClient = new Zend_Service_WindowsAzure_Storage_Blob();
$sharedAccessUrl = storageClient->generateSharedAccessUrl(
'container1',
'',
'c',
'w',
$storageClient ->isoDate(time() - 500),
$storageClient ->isoDate(time() + 3000)
);
The following example code will generate a Shared Access Signature for read access
in a blob named test.txt in a container named "container1"
within a time frame of 3000 seconds.
Example 60.183. Generating a Shared Access Signature for a blob
$storageClient = new Zend_Service_WindowsAzure_Storage_Blob();
$sharedAccessUrl = storageClient->generateSharedAccessUrl(
'container1',
'test.txt',
'b',
'r',
$storageClient ->isoDate(time() - 500),
$storageClient ->isoDate(time() + 3000)
);
When you receive a Shared Access Signature from someone else, you can use the Windows Azure SDK for PHP to work with the addressed resource. For example, the following signature can be retrieved from the owner of a storage account:
http://phpstorage.blob.core.windows.net/phpazuretestshared1?st=2009-08-17T09%3A06%3A17Z&se=2009-08-17T09%3A56%3A17Z&sr=c&sp=w&sig=hscQ7Su1nqd91OfMTwTkxabhJSaspx%2BD%2Fz8UqZAgn9s%3D
The above signature gives write access to the "phpazuretestshared1" "container" of the phpstorage account. Since the shared key for the account is not known, the Shared Access Signature can be used to work with the authorized resource.
Example 60.184. Consuming a Shared Access Signature for a container
$storageClient = new Zend_Service_WindowsAzure_Storage_Blob(
'blob.core.windows.net', 'phpstorage', ''
);
$storageClient->setCredentials(
new Zend_Service_WindowsAzure_Credentials_SharedAccessSignature()
);
$storageClient->getCredentials()->setPermissionSet(array(
'http://phpstorage.blob.core.windows.net/phpazuretestshared1?st=2009-08-17T09%3A06%3A17Z&se=2009-08-17T09%3A56%3A17Z&sr=c&sp=w&sig=hscQ7Su1nqd91OfMTwTkxabhJSaspx%2BD%2Fz8UqZAgn9s%3D'
));
$storageClient->putBlob(
'phpazuretestshared1', 'NewBlob.txt', 'C:\Files\dataforazure.txt'
);
Note that there was no explicit permission to write to a specific blob. Instead, the Windows Azure SDK for PHP determined that a permission was required to either write to that specific blob, or to write to its container. Since only a signature was available for the latter, the Windows Azure SDK for PHP chose those credentials to perform the request on Windows Azure blob storage.
The Table service offers structured storage in the form of tables.
Table Storage is offered by Windows Azure as a REST API which is wrapped by the
Zend_Service_WindowsAzure_Storage_Table class in order to provide a
native PHP interface to the storage account.
This topic lists some examples of using the
Zend_Service_WindowsAzure_Storage_Table class. Other features are
available in the download package, as well as a detailed API documentation of those
features.
Note that development table storage (in the Windows Azure SDK) does not support all features provided by the API. Therefore, the examples listed on this page are to be used on Windows Azure production table storage.
This topic lists some samples of operations that can be executed on tables.
Using the following code, a table can be created on Windows Azure production table storage.
Example 60.185. Creating a table
$storageClient = new Zend_Service_WindowsAzure_Storage_Table(
'table.core.windows.net', 'myaccount', 'myauthkey'
);
$result = $storageClient->createTable('testtable');
echo 'New table name is: ' . $result->Name;
Using the following code, a list of all tables in Windows Azure production table storage can be queried.
Example 60.186. Listing all tables
$storageClient = new Zend_Service_WindowsAzure_Storage_Table(
'table.core.windows.net', 'myaccount', 'myauthkey'
);
$result = $storageClient->listTables();
foreach ($result as $table) {
echo 'Table name is: ' . $table->Name . "\r\n";
}
Tables store data as collections of entities. Entities are similar to rows. An entity has a primary key and a set of properties. A property is a named, typed-value pair, similar to a column.
The Table service does not enforce any schema for tables, so two entities in the same table may have different sets of properties. Developers may choose to enforce a schema on the client side. A table may contain any number of entities.
Zend_Service_WindowsAzure_Storage_Table provides 2 ways of
working with entities:
Enforced schema
No enforced schema
All examples will make use of the following enforced schema class.
Example 60.187. Enforced schema used in samples
class SampleEntity extends Zend_Service_WindowsAzure_Storage_TableEntity
{
/**
* @azure Name
*/
public $Name;
/**
* @azure Age Edm.Int64
*/
public $Age;
/**
* @azure Visible Edm.Boolean
*/
public $Visible = false;
}
Note that if no schema class is passed into table storage methods,
Zend_Service_WindowsAzure_Storage_Table automatically works with
Zend_Service_WindowsAzure_Storage_DynamicTableEntity.
To enforce a schema on the client side using the
Zend_Service_WindowsAzure_Storage_Table class, you can create
a class which inherits
Zend_Service_WindowsAzure_Storage_TableEntity. This class
provides some basic functionality for the
Zend_Service_WindowsAzure_Storage_Table class to work with a
client-side schema.
Base properties provided by
Zend_Service_WindowsAzure_Storage_TableEntity are:
PartitionKey (exposed through getPartitionKey() and
setPartitionKey())
RowKey (exposed through getRowKey() and
setRowKey())
Timestamp (exposed through getTimestamp() and
setTimestamp())
Etag value (exposed through getEtag() and
setEtag())
Here's a sample class inheriting
Zend_Service_WindowsAzure_Storage_TableEntity:
Example 60.188. Sample enforced schema class
class SampleEntity extends Zend_Service_WindowsAzure_Storage_TableEntity
{
/**
* @azure Name
*/
public $Name;
/**
* @azure Age Edm.Int64
*/
public $Age;
/**
* @azure Visible Edm.Boolean
*/
public $Visible = false;
}
The Zend_Service_WindowsAzure_Storage_Table class will map
any class inherited from
Zend_Service_WindowsAzure_Storage_TableEntity to Windows
Azure table storage entities with the correct data type and property name. All there
is to storing a property in Windows Azure is adding a docblock comment to a public
property or public getter/setter, in the following format:
Example 60.189. Enforced property
/** * @azure <property name in Windows Azure> <optional property type> */ public $<property name in PHP>;
Let's see how to define a propety "Age" as an integer on Windows Azure table storage:
Note that a property does not necessarily have to be named the same on Windows Azure table storage. The Windows Azure table storage property name can be defined as well as the type.
The following data types are supported:
Edm.Binary - An array of bytes up to 64 KB in size.
Edm.Boolean - A boolean value.
Edm.DateTime - A 64-bit value expressed as Coordinated
Universal Time (UTC). The supported DateTime range begins from 12:00
midnight, January 1, 1601 A.D. (C.E.), Coordinated Universal Time (UTC). The
range ends at December 31st, 9999.
Edm.Double - A 64-bit floating point value.
Edm.Guid - A 128-bit globally unique identifier.
Edm.Int32 - A 32-bit integer.
Edm.Int64 - A 64-bit integer.
Edm.String - A UTF-16-encoded value. String values may
be up to 64 KB in size.
To use the Zend_Service_WindowsAzure_Storage_Table class
without defining a schema, you can make use of the
Zend_Service_WindowsAzure_Storage_DynamicTableEntity class.
This class inherits Zend_Service_WindowsAzure_Storage_TableEntity
like an enforced schema class does, but contains additional logic to make it dynamic
and not bound to a schema.
Base properties provided by
Zend_Service_WindowsAzure_Storage_DynamicTableEntity are:
PartitionKey (exposed through getPartitionKey() and
setPartitionKey())
RowKey (exposed through getRowKey() and
setRowKey())
Timestamp (exposed through getTimestamp() and
setTimestamp())
Etag value (exposed through getEtag() and
setEtag())
Other properties can be added on the fly. Their Windows Azure table storage type will be determined on-the-fly:
Example 60.191. Dynamicaly adding properties to Zend_Service_WindowsAzure_Storage_DynamicTableEntity
$target = new Zend_Service_WindowsAzure_Storage_DynamicTableEntity(
'partition1', '000001'
);
$target->Name = 'Name'; // Will add property "Name" of type "Edm.String"
$target->Age = 25; // Will add property "Age" of type "Edm.Int32"
Optionally, a property type can be enforced:
Example 60.192. Forcing property types on Zend_Service_WindowsAzure_Storage_DynamicTableEntity
$target = new Zend_Service_WindowsAzure_Storage_DynamicTableEntity(
'partition1', '000001'
);
$target->Name = 'Name'; // Will add property "Name" of type "Edm.String"
$target->Age = 25; // Will add property "Age" of type "Edm.Int32"
// Change type of property "Age" to "Edm.Int32":
$target->setAzurePropertyType('Age', 'Edm.Int64');
The Zend_Service_WindowsAzure_Storage_Table class
automatically works with
Zend_Service_WindowsAzure_Storage_TableEntity if no specific
class is passed into Table Storage methods.
Using the following code, an entity can be inserted into a table named "testtable". Note that the table has already been created before.
Example 60.193. Inserting an entity
$entity = new SampleEntity ('partition1', 'row1');
$entity->FullName = "Maarten";
$entity->Age = 25;
$entity->Visible = true;
$storageClient = new Zend_Service_WindowsAzure_Storage_Table(
'table.core.windows.net', 'myaccount', 'myauthkey'
);
$result = $storageClient->insertEntity('testtable', $entity);
// Check the timestamp and etag of the newly inserted entity
echo 'Timestamp: ' . $result->getTimestamp() . "\n";
echo 'Etag: ' . $result->getEtag() . "\n";
Using the following code, an entity can be retrieved by partition key and row key. Note that the table and entity have already been created before.
Example 60.194. Retrieving an entity by partition key and row key
$storageClient = new Zend_Service_WindowsAzure_Storage_Table(
'table.core.windows.net', 'myaccount', 'myauthkey'
);
$entity= $storageClient->retrieveEntityById(
'testtable', 'partition1', 'row1', 'SampleEntity'
);
Using the following code, an entity can be updated. Note that the table and entity have already been created before.
Example 60.195. Updating an entity
$storageClient = new Zend_Service_WindowsAzure_Storage_Table(
'table.core.windows.net', 'myaccount', 'myauthkey'
);
$entity = $storageClient->retrieveEntityById(
'testtable', 'partition1', 'row1', 'SampleEntity'
);
$entity->Name = 'New name';
$result = $storageClient->updateEntity('testtable', $entity);
If you want to make sure the entity has not been updated before, you can make sure the Etag of the entity is checked. If the entity already has had an update, the update will fail to make sure you do not overwrite any newer data.
Example 60.196. Updating an entity (with Etag check)
$storageClient = new Zend_Service_WindowsAzure_Storage_Table(
'table.core.windows.net', 'myaccount', 'myauthkey'
);
$entity = $storageClient->retrieveEntityById(
'testtable', 'partition1', 'row1', 'SampleEntity'
);
$entity->Name = 'New name';
// last parameter instructs the Etag check:
$result = $storageClient->updateEntity('testtable', $entity, true);
Using the following code, an entity can be deleted. Note that the table and entity have already been created before.
Example 60.197. Deleting an entity
$storageClient = new Zend_Service_WindowsAzure_Storage_Table(
'table.core.windows.net', 'myaccount', 'myauthkey'
);
$entity = $storageClient->retrieveEntityById(
'testtable', 'partition1', 'row1', 'SampleEntity'
);
$result = $storageClient->deleteEntity('testtable', $entity);
Queries in Zend_Service_WindowsAzure_Storage_Table table
storage can be performed in two ways:
By manually creating a filter condition (involving learning a new query language)
By using the fluent interface provided by the
Zend_Service_WindowsAzure_Storage_Table
Using the following code, a table can be queried using a filter condition. Note that the table and entities have already been created before.
Example 60.198. Performing queries using a filter condition
$storageClient = new Zend_Service_WindowsAzure_Storage_Table(
'table.core.windows.net', 'myaccount', 'myauthkey'
);
$entities = $storageClient->storageClient->retrieveEntities(
'testtable',
'Name eq \'Maarten\' and PartitionKey eq \'partition1\'',
'SampleEntity'
);
foreach ($entities as $entity) {
echo 'Name: ' . $entity->Name . "\n";
}
Using the following code, a table can be queried using a fluent interface. Note that the table and entities have already been created before.
Example 60.199. Performing queries using a fluent interface
$storageClient = new Zend_Service_WindowsAzure_Storage_Table(
'table.core.windows.net', 'myaccount', 'myauthkey'
);
$entities = $storageClient->storageClient->retrieveEntities(
'testtable',
$storageClient->select()
->from($tableName)
->where('Name eq ?', 'Maarten')
->andWhere('PartitionKey eq ?', 'partition1'),
'SampleEntity'
);
foreach ($entities as $entity) {
echo 'Name: ' . $entity->Name . "\n";
}
This topic demonstrates how to use the table entity group transaction features provided by Windows Azure table storage. Windows Azure table storage supports batch transactions on entities that are in the same table and belong to the same partition group. A transaction can include at most 100 entities.
The following example uses a batch operation (transaction) to insert a set of entities into the "testtable" table. Note that the table has already been created before.
Example 60.200. Executing a batch operation
$storageClient = new Zend_Service_WindowsAzure_Storage_Table(
'table.core.windows.net', 'myaccount', 'myauthkey'
);
// Start batch
$batch = $storageClient->startBatch();
// Insert entities in batch
$entities = generateEntities();
foreach ($entities as $entity) {
$storageClient->insertEntity($tableName, $entity);
}
// Commit
$batch->commit();
When running a PHP application on the Windows Azure platform in a load-balanced mode
(running 2 Web Role instances or more), it is important that PHP session data can be
shared between multiple Web Role instances. The Windows Azure SDK for PHP provides the
Zend_Service_WindowsAzure_SessionHandler class, which uses
Windows Azure Table Storage as a session handler for PHP applications.
To use the Zend_Service_WindowsAzure_SessionHandler session
handler, it should be registered as the default session handler for your PHP
application:
Example 60.201. Registering table storage session handler
$storageClient = new Zend_Service_WindowsAzure_Storage_Table(
'table.core.windows.net', 'myaccount', 'myauthkey'
);
$sessionHandler = new Zend_Service_WindowsAzure_SessionHandler(
$storageClient , 'sessionstable'
);
$sessionHandler->register();
The above classname registers the
Zend_Service_WindowsAzure_SessionHandler session handler and will
store sessions in a table called "sessionstable".
After registration of the
Zend_Service_WindowsAzure_SessionHandler session handler,
sessions can be started and used in the same way as a normal PHP session:
Example 60.202. Using table storage session handler
$storageClient = new Zend_Service_WindowsAzure_Storage_Table(
'table.core.windows.net', 'myaccount', 'myauthkey'
);
$sessionHandler = new Zend_Service_WindowsAzure_SessionHandler(
$storageClient , 'sessionstable'
);
$sessionHandler->register();
session_start();
if (!isset($_SESSION['firstVisit'])) {
$_SESSION['firstVisit'] = time();
}
// ...
![]() |
Warning |
|---|---|
The |
The Queue service stores messages that may be read by any client who has access to the storage account.
A queue can contain an unlimited number of messages, each of which can be up to 8 KB in size. Messages are generally added to the end of the queue and retrieved from the front of the queue, although first in/first out (FIFO) behavior is not guaranteed. If you need to store messages larger than 8 KB, you can store message data as a queue or in a table and then store a reference to the data as a message in a queue.
Queue Storage is offered by Windows Azure as a REST API which is wrapped
by the Zend_Service_WindowsAzure_Storage_Queue class in order to
provide a native PHP interface to the storage account.
This topic lists some examples of using the
Zend_Service_WindowsAzure_Storage_Queue class. Other features
are available in the download package, as well as a detailed API documentation of those
features.
Using the following code, a queue can be created on development storage.
Example 60.203. Creating a queue
$storageClient = new Zend_Service_WindowsAzure_Storage_Queue();
$result = $storageClient->createQueue('testqueue');
echo 'Queue name is: ' . $result->Name;
Using the following code, a queue can be removed from development storage.
Example 60.204. Deleting a queue
$storageClient = new Zend_Service_WindowsAzure_Storage_Queue();
$storageClient->deleteQueue('testqueue');
Using the following code, a message can be added to a queue on development storage. Note that the queue has already been created before.
Example 60.205. Adding a message to a queue
$storageClient = new Zend_Service_WindowsAzure_Storage_Queue();
// 3600 = time-to-live of the message, if omitted defaults to 7 days
$storageClient->putMessage('testqueue', 'This is a test message', 3600);
Using the following code, a message can be read from a queue on development storage. Note that the queue and message have already been created before.
Example 60.206. Reading a message from a queue
$storageClient = new Zend_Service_WindowsAzure_Storage_Queue();
// retrieve 10 messages at once
$messages = $storageClient->getMessages('testqueue', 10);
foreach ($messages as $message) {
echo $message->MessageText . "\r\n";
}
The messages that are read using getMessages() will be
invisible in the queue for 30 seconds, after which the messages will re-appear in
the queue. To mark a message as processed and remove it from the queue, use the
deleteMessage() method.
Example 60.207. Marking a message as processed
$storageClient = new Zend_Service_WindowsAzure_Storage_Queue();
// retrieve 10 messages at once
$messages = $storageClient->getMessages('testqueue', 10);
foreach ($messages as $message) {
echo $message . "\r\n";
// Mark the message as processed
$storageClient->deleteMessage('testqueue', $message);
}
Using the following code, a queue can be checked for new messages. Note that the queue and message have already been created before.
Example 60.208. Check if there are messages in a queue
$storageClient = new Zend_Service_WindowsAzure_Storage_Queue();
// retrieve 10 messages at once
$messages = $storageClient->peekMessages('testqueue', 10);
foreach ($messages as $message) {
echo $message->MessageText . "\r\n";
}
Note that messages that are read using peekMessages() will
not become invisible in the queue, nor can they be marked as processed using the
deleteMessage() method. To do this, use
getMessages() instead.