Category Archives: Uncategorized

CTP 2 of Microsoft Driver for PHP for SQL Server Released!

I was planning on writing up a long blog post about the CTP of the Microsoft Driver for PHP for SQL Server driver but Brian Swan already did a fantastic job complete with code. Quick snippet from his post:

Here’s a high-level list of the work that was done for this release:

  • Code refactored to share common functionality between the SQLSRV and PDO_SQLSRV drivers.
  • SQLSRV extension is rebuilt with refactored code (no new features).
  • PDO::__construct(): a design change from CTP1, Connection Options now need to be specified in the DSN string instead of the driver_options[] array.
  • PDO::SQLSRV_ATTR_DIRECT_QUERY: new custom driver attribute to provide more flexibility to the developer.
    • Ability to execute two queries within the same context or different contexts (useful for using temp tables and other features that are not always available with prepared statements).
  • Error messages are now encoded per the setting of CharacterSet / PDO::SQLSRV_ATTR_ENCODING.
  • Bug fixes to both the PHP_SQLSRV and PDO_SQLSRV extensions.

My thought on this is that it’s another great step in Microsoft’s working with the PHP community. A colleague actually asked “Am I right we are picking up the tempo in terms of PHP related activity?". I was able to answer with an enthusiastic “Yes”. 🙂

Make sure to check out Brian’ Swan’s Post at CTP 2 of Microsoft Driver for PHP for SQL Server Released.

Resolving PHP Version Conflicts while Developing for Azure

A little while back I wrote a blog post titled Easy Setup for PHP On Azure Development. One of the things that I touched on is the PHP version conflicts. I had a much better idea which I’ve tried and have working so I thought I’d blog that here. What I had you doing in the Easy Setup for PHP On Azure Development is renaming the directory for PHP from something like C:\PHP or C:\Program Files\PHP to something else so that it wasn’t in the %PATH% so there wasn’t a conflict.

The Fix

Reality is that we don’t have to do that. Instead, we can all co-exist happily on the same box. In short, what we’re going to do is load the local version of PHP from our box into the dev fabric rather than using the one that’s bundled with the Eclipse plug-in. The way that we’re going to do that is by using the web.config to specify the location on the local disk where our PHP install is.

That web.config looks something like this:

<?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="c:\program files\php\php-cgi.exe"
           resourceType="Unspecified" />
      <!--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>
    
  </system.webServer>
</configuration>

Notice that I’ve commented out the original handler that setup the processer with the %RoleRoot%\approot\… We’ll need that when we go live but for now, we’ll use the one that’s actually using the hard path on my local disk.

The exciting part about it is that we’ll be able to use our own version of PHP with all of the extensions that we normally use and configured exactly to taste.

Testing Local

The other exciting thing is that you can actually test any of your WebRole code against your local IIS rather than having to deploy it to the DevFabric every time you want to test. Deploying to the DevFabric takes time and so I’ve found myself taking more time and slinging just a little more code than I should before doing my testing. Against my local IIS box, I’m able to just refresh the browser and see instant results. I still definitely recommend running in the DevFabric because it’s as close to the real environment as you’re going to get at the moment.

image To test against your local IIS with the same exact source code and folders, simply set up the directory as a Virtual Directory. To do that, you need to do one of two things. You can open up the IIS manager and add it that way or you can use Powershell to do it.

In IIS manager, expand the navigation tree down to find the web site that you want to deploy your virtual directory on (typically this is “Default Web Site”) and right click. Then select Add Virtual Directory and fill out the wizard with the alias (e.g. myproject will end up with http://localhost/myproject) and the physical path that you want to use.

If you decide to go with the PowerShell option and do it from the command line, there’s a great cmdlet (Powershell script) called New-WebVirtualDirectory that you can leverage. Make sure that you read the instructions on how to Import All Modules.

The Catch

Now, the issue that you’ll have with this is that when you do actually go to deploy to the cloud, you’ll need to either retest with the version of PHP that’s bundled by default by the Eclipse tooling or make your deployment package by hand with the command line tools.

My recommendation is rolling your own package with the command line tools. Really all you need to do is use CSPack (and possibly CSRun to test locally) from my blog post at Windows Azure Command Line Tools.

Additionally, The great news there is that there’s some great tools available for you at http://azurephptools.codeplex.com/.

Wrap up

I’m much happier with this solution than I was with the whole renaming the directory hack. It worked but it was a pain when switching between regular and Azure development. This way, regular and Azure development are seamless.

WordPress Podcast

image

I was thrilled and honored to be a guest on the WordPress Podcast on WebMasterRadio.fm. This podcast is hosted by my friend Joost de Valk and Frederick Townes.

image I met Joost back at WordCamp Ireland back in March. That was a fun time. He and I talked about just about everything from being fathers to deep technical bits comparing various types of caching mechanisms. He even helped me with a number of SEO tips on my web site. Not sure if you’ve noticed but I’m turning up in a lot more searches thanks to him – he knows his stuff. Don’t believe me? Think just for a moment about how competitive this field is and then do a search for WordPress SEO in your favorite search engine and tell me what you think then… 😉

image I haven’t actually met Frederick yet but he comes with just a touch of credibility himself being the CTO of Mashable. He’s also the maintainer of the W3 Total Cache plugin. I’m a little jealous of him at the moment though as he’s been based in Florence, Italy for the past year or so… Must be rough.

One thing I will say though is that it’s becoming imperative that I get one of those spankin cartoon avatars.

The show was good but it *flew* by. Before I knew it, the WebMasterRadio dude was IMing us that we had 2 minutes left. All I could think about at points was that I hadn’t even mentioned the SEO toolkit, Windows Live Writer, URL Rewrite and a ton of other stuff that I wanted to get to. Oh well, we talked about a bunch of stuff. Maybe I can convince them there’s enough interesting content to do another show at some point.

So, what I did have time to talk about was a bunch of stuff. We started off with a little bit about me – (which is always a little embarrassing and I hate doing it but it is what it is).

Why the bleep is Microsoft doing this?!Joost started off by talking about how I ended up on the show in the first place. About a month ago, Zach Owens and some other guys from Redmond launched a site called http://wordpress.visitmix.com which talks about running WordPress on Windows and how great of an experience that can be. Not only that but there’s another micro-site that just went up at http://www.microsoft.com/web/wordpress. On both of these sites you can find links to the Web Platform Installer, the SQL Server plug-in for WordPress (in beta right now), plug-ins written by Microsoft for WordPress such as Windows Azure Storage for WordPress which allows us to store our files on Azure Storage for all of our media. 

I don’t know if you’ve noticed, but this site (JoshHolmes.com) is actually a WordPress blog as well. I switched over from dasBlog a few months back. dasBlog served me well but it was getting time to move on and WordPress was at the top of the list. Joost was actually the one that convinced me to migrate to WordPress. It didn’t take a tremendous amount of work to do it either. I used DasBlogML to suck out all of the content and then I imported it into WordPress, converted my theme over and was happy.

In addition to WordPress specific things stuff going on at Microsoft, there’s been a lot of support for PHP in general that has gone into IIS, SQL Server and many more of the Microsoft platforms. WinCache, for example, is a great caching tool for PHP on IIS. Just turning it on will result in a 3x or so improvement in performance in PHP on IIS. RuslanY has a great post on getting WinCache support into WordPress. And if you want to see how well it’s working, check out this module that shows you WinCache stats in WordPress. It was written by Kanwaljeet Singla who is the engineer behing FastCGI and WinCache. Cool stuff.

We also talked a little about JumpIn Camp and what happened there. phpBB getting into the Web Application Gallery and adding SQL Server support was one of the huge things that came out of that. 

image We also chatted about SQL Server a little. Frederick asked me about, to frame it in context for those that are not database or back end nuts, why this was important. It was a good question. In short, there’s a couple of really good reasons why someone would care. The first is that if one is at a company that already has SQL Server, it’s going to make a lot more sense to stand up your WordPress blog on SQL Server rather than introducing a new database engine and more administration to the existing infrastructure. A second great reason is that SQL Server has a ton of fantastic features that WordPress module authors could leverage such as Spatial Data or the fantastic analytics and reporting services that it offers. I teased Joost a little on the podcast about writing a module about that, but I think he knows as well as I do that I was serious as a heart attack that it would be an awesome set of modules. I’m hoping that Joost and others will take that challenge and run with it. If you do, let me know – I’ll be happy to help with whatever technical know-how that you need.

image Then we turned to PHP on Azure. This happens to be a passion of mine and I talk about it a lot… 🙂 I probably rambled a little on it talking about the differences between Infrastructure as a Service (IaaS) and Platform as a Service (PaaS) and what specifically Azure offers. If I was redoing the conversation, I would have cut a little on this conversation in favor of some of the things I didn’t mention such as URL rewrite… Oh well – I’ll do that here.

After that we went back to talking about the plug-ins that we found on http://www.microsoft.com/web/wordpress. There’s a handful of really good ones out there. One that struck Joost’s fancy is the Bing Maps plug in. Using WordPress short code and this plug in, it’s really simple to throw in a Bing Map on your blog.

Somewhere in here we were given the 2 minute warning.

All I had time left to talk about was the Toughest Developer Puzzle Ever.

I had a blast on the podcast and hope to be a repeat guest at some point. 

Toughest Developer Puzzle Ever

image For the second year in a row, my friend and colleague Jeff Blankenburg has created what is quickly proving to live up to it’s namesake – the Toughest Developer Puzzle Ever.

Some of the puzzles are technical, some are not but all require that you understand the web, development and technology to solve. Even if you don’t get in on the fantastic prizes that Jeff has lined up, there’s great bragging rights in being able to solve the Toughest Developer Puzzle Ever.

This year, I was honored enough to get to create three of the puzzles myself – let me know what you think of them. I’m not going to tell you which ones I created now and definitely don’t ask me for hints – Jeff has threatened me if I give any of the puzzle away… 😉

All I can say now is “Good luck!”

phpBB is in the Web Application Gallery

image You might have seen me tweet about the fact that PHPBB had submitted to the Web Application Gallery a couple of weeks back. Well, it’s official – the phpBB package has been finished, tested and accepted into the Web Application Gallery. You can see the official announcement on the Microsoft Web Platform blog. That means that you can install phpBB on Windows through the Web Platform Installer (WebPI) which gives you a very simple wizard to walk through.

Try phpBB on the Microsoft Web Platform today!

 

The WebPI will take a look at the dependencies that the project has requested and pull those in as well. In the case of phpBB, this includes PHP 5.2.13 (and higher when the WebPI supports it), SQL Server (Yes, I said SQL Server!) and more. It will configure IIS for FastCGI support and the whole nine yards.

The work to accomplish all of this awesome support was done at JumpIn Camp by Nils Aderman, Chris Smith and Henry Sudhof of the phpBB core team. I’ll be talking a lot more about JumpIn Camp over the next couple of weeks but in short, JumpIn Camp was an event that I helped organize, along with Yuriy Zaytsev, Will Coleman and Bram Veenhof in Zurich, Switzerland. There were contributors from a number of the top PHP applications in the world that attended for the opportunity to work on their own projects to support various Microsoft technologies (such as IIS, WebPI, SQL Server, SQL Azure, Silverlight…) with Microsoft technology experts available for technical support.

The SQL Server patch was developed by Microsoft in line with our interoperability efforts in the open source community. The new SQL Server for PHP 1.1 driver that was released back in October, 2009 enables phpBB with UTF-8 on SQL Server, Multiple Active Record Sets (MARS) and the ability to leverage SQL Azure. phpBB has accepted that patch now in their 3.0.7 release.

There are a couple more things that are exciting about all of this to me.

First, it only took a handful of days at JumpIn Camp to pull together the WebPI package + WinCache support for superior performance on Windows. For full disclosure there was some testing and a few minor bugs fixed since then but the lions share of the work was done at JumpIn Camp.

Second, phpBB is the first of the PHP application that can be installed through the WebPI with SQL Server support. I’m hoping that it will become the trend now that the SQL Server Driver for PHP 2.0 CTP with PDO is in CTP and people can start playing with it. I know that there are several applications that are starting testing with the new driver.

Third, it was a ton of fun to get to know the folks from phpBB and all of the folks that attended JumpIn Camp. I’ve been chatting with Nils online for about 6-9 months now but this was the first time that I had met him in person.

Wrapping up – I’m looking forward to seeing a lot more of the work that came out of the JumpIn Camp wrapping up and going public over the next handful of months. It’s going to be a fun time.

Miami 311: Built on Windows Azure

This is a cool use of Azure. The city of Miami tool their “311” data around potholes, trash pickup issues, recycling issues, broken sidewalks and the like and put that data in Azure. The next step is that they leveraged Bing Maps and Silverlight to visualize those issues spread on a map of the city.

The solution takes advantage of virtually unlimited storage and processing power, provides the ability to quickly address service requests and implement updates even during peak times such as hurricane season. If things change, the City can bring the solution on site or move to a physical facility, all based on  need and cost-effectiveness.

As a result, residents logging on to Miami 311 can see on average 4,500 issues in progress – not represented as a ‘list’, but located on a map in relation to other projects in their neighborhood .  A simple click on the map allows them to easily drill down to more and more specific details if they want.

In short, they have turned what used to be represented by a meaningless list of data into useful information, and created  actionable and consumable knowledge that is relevant to the citizens of Miami. For Miami, their ‘service call to the city’ becomes an interactive process they can follow – and the City has a new tool to manage and deliver outcomes.

When the city made the move to the web, they chose tools they knew and software they trust. The Microsoft Windows Azure cloud platform made it easy to do, and they used both Bing mapping and Silverlight to build a user friendly front end.

According to Port25 (Miami 311: Built on Windows Azure – Port 25: The Open Source Community at Microsoft), it took two people 8 days to implement the whole system and they are going to open source their solution so that other cities can leverage it. I haven’t seen yet where and how they are going to release it but I’ll keep you posted if I find out.

Microsoft Contributing More to OSS

image I’m all excited – Microsoft has signed the Joomla! Contributor Agreement. You can read about that on the official Joomla! blog – Microsoft signs the Joomla! Contributor Agreement.

There’s a couple of fairly momentous things about that statement.

Obviously it means that Microsoft employees can contribute to Joomla!. That’s exciting all by itself as Joomla! is the second largest PHP application in the world. In fact, that’s already happened in conjunction with the signing as Ruslan Yakushev and Don Raman have already contributed code to add WinCache support to Joomla! Read all about the fantastic performance gains that you can get in Don’s post here – http://blogs.iis.net/donraman/archive/2010/03/05/performance-improvement-in-joomla-using-wincache-user-cache.aspx.

However, the thing that’s really exciting to me is that what it means is that the Microsoft legal department has signed off on writing GPL’d code under the right circumstances. That’s awesome! It’s a clear demonstration of how far Microsoft has come in it’s commitment to OSS projects. Now, I’ve got my own issues with the GPL as I think that it strips the consumer of all of their rights but that’s for a different discussion.

At this point we have a ton of great OSS work going on.

IronRuby is actually accepting contributions back.

Microsoft has contributed 20k lines of code to the Linux Kernel

There’s the CodePlex.com OSS project hosting.

In fact, there’s a list of over 400 projects that Microsoft is participating in actively at http://www.microsoft.com/opensource/directory.aspx.

And that list is not all inclusive as the SQL Server team has contributed code to a lot of different projects including PHPBB.

It’s a fun time to be working at Microsoft as we are in a transformational period finding the right balance between OSS and proprietary code, between selling stuff in boxes to finding interesting ways to monetize online beyond just ad sales and much more.

Microsoft UX Kit

image Have you ever wondered what was possible with Silverlight, WPF or any of Microsoft’s User Experience (UX) technologies? Well, Christian Thilmany has answered that question in the form of the Microsoft UX Kit.

From his blog:

Today at SXSW, of which Microsoft Silverlight is a major sponsor of the Interactive Festival,  Microsoft User Experience Kit is targeted at technical and creative leads who want to better understand the tools, technologies, and scenarios that span Microsoft’s User Experience ecosystem.  Key topics range from “Building Immersive Multi-channel Solutions using Expression Studio” to “High fidelity and high Performing Desktop Touch Applications using Windows 7” to “Web Branding and Audience Targeting using SharePoint”.  The kit’s contents can be browsed online and/or downloaded for offline use.  It includes videos, presentations, sample code, and much more. Get the kit at http://uxkit.cloudapp.net!

It’s done a lot for me in helping opening my eyes to new ideas around media publishing, audience marketing, how to leverage the 3 screen types (Desktop, TV, Mobile) and a lot more. It’s really excited my imagination.

That and there’s a ton of good code that you can download from the site as well so you can get some really god jump starts on the code.

 

Microsoft User Experience Kit launched today at SXSW

PDO Driver for SQL Server CTP

The SQL Server team had a great announcement yesterday at DrupalCon in San Francisco. They announced the availability of a PDO Driver for SQL Server to give fantastic access to SQL Server from PHP. PDO is the PHP Data Objects extension that has become the standard way to do data access in PHP 5.0 or later projects that want to have some level of database agnosticism. Drupal, for example, uses the PDO driver for all of it’s database access.

The rough architecture for the 1.1 and 2.0 SQL Server drivers is outline below.

image 

In short, they centralized a lot of the core functionality into a common layer and have fairly thin wrappers over the top of that for the native and PDO drivers. This means that both will perform equally.

The great news for anyone who has written their applications with PDO rather than native drivers for a given database is that they should be able to plug in the new SQL Server PDO driver and start testing.

To be absolutely clear, however, PDO is not a full database abstraction. It doesn’t rewrite SQL statements of abstract away concepts such as MySQL Limits and the like. If you are using database specific features like that, you will have to rewrite those bits in your project.

See the official announcement on the SQL Server team’s blog at Interoperability @ Microsoft : SQL Server Driver for PHP 2.0 CTP adds PHP’s PDO style data access for SQL Server

Creating a Simple PHP Blog in Azure

In this post, I want to walk through creating a simple Azure application that will show a few pages, leverage Blob storage, Table storage and generally get you started doing PHP on Azure development. In short, we are going to write a very simple PHP Blog engine for Azure.

To be very clear, this is not a pro blog engine and I don’t recommend using it in production. It’s a lab for you to try some things out and play with PHP on Azure development.

If you feel like cheating, all of the source code is available in the zip file at https://joshholmes.com/downloads/pablogengine001.zip.

0. Before you get started, you need to make sure that you have the PHP on Azure development environment setup. If you don’t, please follow the instructions at Easy Setup for PHP On Azure Development.

image

Create a Windows Azure Web Project

1. To accomplish this, click on File | New | Project.

2. In the New PHP Azure Web Project page, name the project PABlogEngine (for PHP on Azure Blog Engine).

3. Next you need to select Windows Azure Data Storage. Notice that we’re not selecting SQL Storage. We are going to be using Table and Blob Storage for this project.

4. Click Finish

Creating a Table Entity in PHP

The next step is to get a little setup stuff done. We are going to be using Entities to put into our Table.

1. Create a file called PABlogPost.php. This is going to contain our Entity that we are going to put into our Azure Table storage.

2. Fill out the PABlogPost.php as follows:

<?php
/*
 * Include the Windows Azure Table Storage helper class from the 
 * Windows Azure for PHP SDK
 */
require_once 'Microsoft/WindowsAzure/Storage/Table.php';

class PABlogPost extends Microsoft_WindowsAzure_Storage_TableEntity
{
    /*
     * Notice the Doctrine style comments, some of which, 
     * such as $ImageType, have typing information. 
     * Anything that doesn't have a type is stored as a string. 
     */
    
    /**
     * @azure Title
     */
    public $Title;
    
    /**
     * @azure Description
     */
    public $Description;
    
    /**
     * @azure Author
     */
    public $Author;
    
    /**
     * @azure pubDate
     */
    public $pubDate;
    
    /**
     * @azure Image
     */
    public $Image;
    
    /**
     * @azure ImageUrlOriginal
     */
    public $ImageUrlOriginal;
    
    /**
     * @azure Type
     */
    public $ImageType;
    
    /**
     * @azure Size Edm.Int64
     */
    public $ImageSize;
    
    /**
     * @azure Visible Edm.Boolean
     */
    public $Visible = false;
}
?>

Setting up the utilities

The next step is to get a couple more utilities in place prior to actually writing our application. Specifically, we have two utility functions that we need to hit on and some system wide values.

1. Create a file called utility.php

2. Add the following two values to it.

$BLOG_TABLE = "blogposts";
$BLOG_POSTS_PARTITION = "posts";

We will use these whenever we are going to be accessing the table and or partition. This will let us quickly change them in one place if we ever need to.

The next thing that we need to do is have a consistent way to create our Table Storage Client as we’re using it on more than one page.

3. Add a function called createTableStorageClient as follows:

/**
 * Create Table Storage Client for table operations using account defined in ServiceConfiguration file
 *
 * @return Microsoft_WindowsAzure_Storage_Table New storageclient for Azure Storage Table
 */ 
function createTableStorageClient()
{
  if (isset($_SERVER['USERDOMAIN']) && $_SERVER['USERDOMAIN'] == 'CIS')
  {
    $host = Microsoft_WindowsAzure_Storage::URL_CLOUD_TABLE;
    $accountName = azure_getconfig('AzureCloudStorageAccountName');
    $accountKey = azure_getconfig('AzureCloudStorageAccountKey');
    $usePathStyleUri = true;
    
    $retryPolicy = Microsoft_WindowsAzure_RetryPolicy::retryN(10, 250);
    
    $tableStorageClient = new Microsoft_WindowsAzure_Storage_Table(
                              $host,
                              $accountName,
                              $accountKey,
                              $usePathStyleUri,
                              $retryPolicy
                              );
  }
  else
  {
    $tableStorageClient = new Microsoft_WindowsAzure_Storage_Table();
  }
        
	return $tableStorageClient;
}

4. Lastly, we will need a unique identifier. I’m going to follow Maarten’s lead from the sample code that he’s produced and create a UUID with the following function.

// Generate UUID
function generateUuid($prefix = '')
{
	$chars = md5(uniqid(mt_rand(), true));
	$uuid  = substr($chars,0,8) . '-';
	$uuid .= substr($chars,8,4) . '-';
	$uuid .= substr($chars,12,4) . '-';
	$uuid .= substr($chars,16,4) . '-';
	$uuid .= substr($chars,20,12);
	return $prefix . $uuid;
}

Saving to Windows Azure Table Storage and Windows Azure Blob Storage

There are actually several steps to creating a new post. The first is gathering the information. Next is inserting the post into the table. After that, inserting any images et all into the blob storage, then updating the table if needed with that new information.

1. Create a file called CreateNewPost.php.

2. Insert any template/html code that you want to make it look decent but the primary thing that you need in this page is a form that will accept the correct data do a post back to a file called newpost.php as follows:

<form enctype="multipart/form-data" method="post" action="NewPost.php">
<input value="1048576" type="hidden" name="MAX_FILE_SIZE" />
Title:
<input name="posttitle" /><br />
Description:
<textarea rows="5" name="postdescription" type="text"></textarea><br />
Author:
<input name="postauthor" /><br />
Choose an image to upload:
<input type="file" name="imageUpload" /><br />
<br />
<input value="Create Post" type="submit" />
</form>

3. Create a new file called newpost.php

<?php
// Note that this code is NOT safe against various attacks and should be
// used for demonstrating the concepts of the application only.
// NEVER deploy to production without building correct checks!

// 1. Specify include path and include Windows Azure SDK for PHP
set_include_path( get_include_path() . PATH_SEPARATOR . $_SERVER["RoleRoot"]);
require_once 'utility.php';
require_once 'PABlogPost.php';

require_once 'Microsoft/WindowsAzure/Storage/Table.php';
require_once 'Microsoft/WindowsAzure/Storage/Blob.php';

// 2. Instantiate services and make sure table and blob container exist
$tableStorageClient = new Microsoft_WindowsAzure_Storage_Table();
if (!$tableStorageClient->tableExists($BLOG_TABLE))
{
	$tableStorageClient->createTable($BLOG_TABLE);
}

$blobStorageClient = new Microsoft_WindowsAzure_Storage_Blob();
if (!$blobStorageClient->containerExists($BLOG_TABLE))
{
	$blobStorageClient->createContainer($BLOG_TABLE);
	$blobStorageClient->setContainerAcl($BLOG_TABLE, Microsoft_WindowsAzure_Storage_Blob::ACL_PUBLIC);
}

// 3. Add a record in Windows Azure Table Storage
$newpost = new PABlogPost($BLOG_POSTS_PARTITION, generateUuid());
$newpost->Title = $_POST["posttitle"]; 
$newpost->Description = $_POST["postdescription"]; 
$newpost->Author = $_POST["postauthor"]; 
$newpost->Image = $_FILES['imageUpload']['name'];
$newpost->ImageType = $_FILES['imageUpload']['type'];
$newpost->ImageSize = $_FILES['imageUpload']['size'];
$newpost->UrlOriginal = '';
$newpost = $tableStorageClient->insertEntity($BLOG_TABLE, $newpost);

// 4. Upload the image to blob storage
$blob = $blobStorageClient->putBlob($BLOG_TABLE, $newpost->getRowKey(), $_FILES['imageUpload']['tmp_name']);

// 5. Update the post to reflect the new image URL in the table
$newpost->ImageUrlOriginal = $blob->Url;
$newpost= $tableStorageClient->updateEntity($BLOG_TABLE, $newpost);

?>
<h1>New Post up!</h1>
    
<p>
	Your post has been created. Navigate to
	<!-- 6. Show the results -->
	<a href="post.php?id=<?php echo $newpost->getRowKey(); ?>"><?php echo $newpost->Title; ?></a>
	to see your new post.
</p>

Reading from Windows Azure Table Storage

We are almost done. The last thing that we need to do is to show the results for a specific post and to modify the index.php to show all of the posts.

1. Create a new file called post.php. We already referred to this page in the newpost.php file.

2. Fill out this post.php as follows:

<?php
set_include_path( get_include_path() . PATH_SEPARATOR . $_SERVER["RoleRoot"]);
require_once 'utility.php';
require_once 'PABlogPost.php';
// 1. Include the table storage information

require_once 'Microsoft/WindowsAzure/Storage/Table.php'; // 2. Instantiate services $tableStorageClient = new Microsoft_WindowsAzure_Storage_Table(); // 3. Fetch post details $Id = $_REQUEST['id']; $post = $tableStorageClient->retrieveEntityById($BLOG_TABLE, $BLOG_POSTS_PARTITION, $Id); ?> <h1><?php echo $post->Title; ?></h1> <table border="0" cellspacing="0" cellpadding="2"> <tr> <td rowspan="2"> <img src="<?php echo $post->ImageUrlOriginal; ?>" alt="<?php echo $post->Title; ?>" /> </td> <td> <?php echo ' - Title: <b>' . $post->Title . "</b><br/>"; echo ' - Description: ' . $post->Description . "<br/>"; echo ' - Author: ' . $post->Author . "<br/>"; echo ' - Author: ' . $post->Author . "<br/>"; echo ' - pubDate ' - $post->pubDate . "<br/>"; ?> </td> </tr> </table> <a href='/'>Home</a>

There’s a couple of things to notice about this code.

First, notice that we’re not talking to blob storage in the PHP code. All we are doing is putting in a link to the blob with the $post->ImageUrlOriginal. This is because the blob storage is giving us a restful endpoint that we need.

Another thing to notice is that it’s not doing any checks for exceptions. You will want to do that in your code.

3. The last thing that we need to do is the index.php. Fill it out as follows:

<?php
set_include_path(get_include_path() . PATH_SEPARATOR . $_SERVER["RoleRoot"] . "\\approot\\");

require_once 'utility.php';
require_once 'PABlogPost.php';
/**
 * Refer PHP Azure SDK library files for Azure Storage Services Operations
 */
require_once 'Microsoft/WindowsAzure/Storage.php';
require_once 'Microsoft/WindowsAzure/Storage/Table.php';

$tableStorageClient = createTableStorageClient();

if ($tableStorageClient->tableExists($BLOG_TABLE))
{
	/**
	 * Performing queries. Notice that we are not using a filter. 
	 */
	$posts = $tableStorageClient->retrieveEntities(
		$BLOG_TABLE,
		'',
		'PABlogPost'
	);

	echo "Blog posts:<br />";
	foreach ($posts as $post)
	{
		echo '<p>';
		echo '<b><a href="post.php?id=' . $post->getRowKey() . 
			'">' .$post->Title . '</a></b>';
		echo ' - Description: ' . $post->Description . "<br/>";
		echo ' - Author: ' . $post->Author . "<br/>";
		echo ' - Author: ' . $post->Author . "<br/>";
		echo '</p>';
	}
}
?>

imageConclusion

At this point, we have a very rudimentary blog written in PHP on the Azure platform that is using Table Storage and Blob Storage for all of it’s data. Couple of key points to hit on are that this is not using a traditional database.

I will very likely continue to enhance this little toy application over time as I try showing off more and more things in PHP on Azure.

Again, all of the source code is available in the zip file at https://joshholmes.com/downloads/pablogengine001.zip.

*Update* Someone was having issues with this one and emailed me. The error that they were getting was:

Fatal error: Uncaught exception ‘Microsoft_Http_Transport_Exception’ with message ‘cURL error occured during request for http://127.0.0.1:10002/devstoreaccount1/Tables?NextTableName=test: 7 – couldn’t connect to host’

Turns out that they had not started the Development Storage service so there was nothing for cURL to connect to in the first place. To start it, start the Development Fabric (the computation engine). Once the Development Fabric is up and running, you will need to right click on the Dev Fabric icon in the system tray and select Start Development Storage Service.

clip_image001

At this point you should be good to go.

BTW – if you actually play with this code, I’d love to hear about your experiences with it either in email at josh (dot) holmes (at) microsoft (dot) com or in the comments below.