Thu, 19 Mar 2009

PHP + ASP.NET in Windows Azure

Today at MIX, I showed a new demo application I developed called “Tweval” (Twitter + eval).  Tweval lets you evaluate anything (like my session at MIX) just by tweeting a simple message.  It’s built on top of Botomatic.

tweval screenshot

Tweval takes advantage of one of the coolest things about the MIX announcements we made earlier today, which is that Windows Azure can now run PHP (or indeed anything compatible with FastCGI).  In fact, in Tweval, I’m running ASP.NET MVC code side-by-side with PHP code.

Here’s the architecture diagram from my slides today:

tweval architecture

This diagram shows PHP serving all the UI, but in actuality, both ASP.NET and PHP are rendering UI, as you can see at and (note the bottom right corner of the page).

Using Storage from PHP

Windows Azure storage is accessible via a REST API, but in practice very few people write code directly against the REST endpoint, instead using the sample storage client library that ships with the Windows Azure SDK.  Now that we’ve added support for PHP, many people are wondering where the storage client library is for PHP.  One option that I saw recently is Maarten Balliauw’s PHP library.  Currently it only supports blob storage, but he tells me he’s working on tables and queues next.

For, I didn’t use a client library at all.  I rolled my own function to perform the specific query I needed.  Here’s the code I used:

function fetch($pkey) {
    $date = gmdate('D, d M Y H:i:s \G\M\T');
    $stringtosign = "GET\n\n\n$date\n/tweval/TagRatingTable()";
    $signature = 'SharedKey tweval:'.base64_encode(
        hash_hmac('sha256', $stringtosign, base64_decode($key),true));
    $session = curl_init(''
        .'?$filter=PartitionKey%20eq%20\'' . urlencode($pkey) . '\'');
    curl_setopt($session, CURLOPT_HTTPHEADER, array("x-ms-date:$date", "Authorization:$signature"));
    curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($session);
    $result = array();
    foreach(simplexml_load_string($response)->entry as $entry) {
        $properties =
        $result[] = new Rating((string)($properties>Username), (int)($properties>StatusId),
            (float)($properties>Score), (string)($properties>Tweet), new DateTime($properties>CreatedAt));
    usort($result, 'cmp');
    return $result;

The most difficult part in writing this is signing headers for authentication.  I hope the above sample helps others to get started doing this in PHP.  For another example of using the REST API, please see the Python library Sriram Krishnan and I have been working on:  He also has Erlang bindings.

Prettier URLs with Rewriting

One thing we’ve enabled in the new CTP that’s somewhat buried in the rest of the announcements is support for the IIS URL Rewrite module.  Using that, I got nice URLs like to map to the uglier  Here’s what the rewrite rule looks like:

        <rule name="php">
          <match url="^([^/]*)\.php$" />
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
          <action type="Rewrite" url="index.php?tag={R:1}" />

Just the Beginning of an Open Platform

The main thing I hope everyone takes away from the announcements today is that we’re committed to making Windows Azure an open platform.  This is just the beginning of the work we’ll be doing to ensure that all development tools and technologies have a place in the Windows Azure cloud.

Let me know your thoughts on what we’ve done so far and your suggestions for future work.