Windows Azure - PHP contributions
PhpAzureExtensions - AzureDriveModule
The
AzureDriveModule is part of the
PhpAzureExtensions subproject and based on
Jeff Tanner's proposal on MSDN forums.
Introduction
Windows Azure has different storage options like blobs, tables, queues and drives. There’s the
Windows Azure SDK for PHP for most of this, except for drives. Which is normal: drives are at the operating system level and have nothing to do with the REST calls that are used for the other storage types.
Unfortunately, .NET code is currently the only way to create and mount these virtual hard drives from Windows Azure. But luckily, IIS7 has this integrated pipeline model which Windows Azure is also using. Among other things, this means that services provided by managed modules (written in .NET) can now be applied to all requests to the server, not just ones handled by ASP.NET! In even other words: you can have some .NET code running in the same request pipeline as the FastCGI process running PHP (or Ruby).
There are 4 steps involved in using the Windows Azure Drive HTTP module:
- Copy the .NET assemblies into your project
- Edit ServiceConfiguration.cscfg (and ServiceDefinition.csdef)
- Edit Web.config
- Use the thing!
Copy the .NET assemblies into your project
Create a
/bin folder in your web role project and copy in all .DLL files provided. Here’s a screenshot of how this looks:
Edit ServiceConfiguration.cscfg (and ServiceDefinition.csdef)
In order to be able to mount, some modifications to ServiceConfiguration.cscfg (and ServiceDefinition.csdef) are required. The ServiceDefinition.csdef file should contain the following additional entries:
<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="DriveTest" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
<WebRole name="WebRole" enableNativeCodeExecution="true">
<ConfigurationSettings>
<Setting name="MountDrives" />
<Setting name="driveconnection" />
</ConfigurationSettings>
<LocalResources>
<LocalStorage name="MyDriveCacheA"
cleanOnRoleRecycle="false"
sizeInMB="1000" />
<LocalStorage name="MyDriveCacheB"
cleanOnRoleRecycle="false"
sizeInMB="1000" />
</LocalResources>
<InputEndpoints>
<!-- Must use port 80 for http and port 443 for https when running in the cloud -->
<InputEndpoint name="HttpIn" protocol="http" port="80" />
</InputEndpoints>
</WebRole>
</ServiceDefinition>
Things to note are the
MyDriveCacheA and
MyDriveCacheB local storage entry, which is needed for caching access to the virtual drive. The configuration settings are defined for use in ServiceConfiguration.csdef:
<?xml version="1.0"?>
<ServiceConfiguration serviceName="DriveTest" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration">
<Role name="WebRole">
<Instances count="1"/>
<ConfigurationSettings>
<Setting name="MountDrives" value="
drive_label=DriveA,connection_string=driveconnection,local_cache=MyDriveCacheA,page_blob_container=drive-container-a,page_blob_vhd=MyDriveA,drive_size=20;
drive_label=DriveB,connection_string=driveconnection,local_cache=MyDriveCacheA,page_blob_container=drive-container-a,page_blob_vhd=MyDriveB,drive_size=40,mount_read_cache_size=10;"/>
<Setting name="driveconnection" value="UseDevelopmentStorage=true" />
</ConfigurationSettings>
</Role>
</ServiceConfiguration>
The configuration specifies that some cloud drives should be mounted (configured in the
MountDrives setting). The following configuration options are available:
| Setting key | Required? | Description |
| drive_label | Yes | Label for drive definition |
| connection_string | Yes | Reference to a connection string |
| local_cache | Yes | Reference to a local resource configuration where the VHD file will be cached |
| page_blob_container | Yes | Blob container where the VHD file will be stored (3 through 63 lower-case characters long) |
| page_blob_vhd | Yes | Name of the blob where the VHD file will be stored (1 to 1024 any combination of characters long) |
| drive_size | Yes | Size of the drive in MB (16 to 1000000) |
| mount_read_cache_size | Optional | Mount Read Cache Size (0 to drive_size) |
| recreate | Optional | Recreate drive pageblobvhd if it already exists in pageblobcontainer |
| readonly | Optional | Snapshot and mount a read-only copy of the drive |
Edit Web.config
Before the HTTP module is used by IIS7 or Windows Azure, the following should be added to Web.config:
<modules>
<add name="AzureDriveModule" type="PhpAzureExtensions.AzureDriveModule, PhpAzureExtensions"/>
</modules>
Here’s my complete Web.config:
<?xml version="1.0"?>
<configuration>
<system.webServer>
<!-- DO NOT REMOVE: PHP FastCGI Module Handler -->
<handlers>
<clear />
<add name="PHP via FastCGI"
path="*.php"
verb="*"
modules="FastCgiModule"
scriptProcessor="%RoleRoot%\approot\php\php-cgi.exe"
resourceType="Unspecified" />
<add name="StaticFile" path="*" verb="*" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" resourceType="Either" requireAccess="Read" />
</handlers>
<!-- Example WebRole IIS 7 Configation -->
<defaultDocument>
<files>
<clear />
<add value="index.php" />
</files>
</defaultDocument>
<modules>
<add name="AzureDriveModule" type="PhpAzureExtensions.AzureDriveModule, PhpAzureExtensions"/>
</modules>
</system.webServer>
</configuration>
Use the thing!
Next thing to do is use your virtual Windows Azure Drive. The HTTP module adds an entry in the $_SERVER variable, named after the drive_label settings defined earlier. The following code example stores a file on a virtual Windows Azure Drive and reads it back afterwards:
<?php
file_put_contents($_SERVER['DriveA'] . '\sample.txt', 'Hello World!');
echo file_get_contents($_SERVER['DriveA'] . '\sample.txt');
?>