Tag Archives: PHP

Zend SimpleCloud and Azure

image I’ve been playing with Zend’s SimpleCloud API for the webcast that I’m doing with Zend today. I started with the Zend Framework Quickstart tutorial but changed out the backend to hit the Azure Tables and such (well kinda – I used Zend Studio 8 Beta 2 and didn’t use the ZF tool but I still created a little guestbook). I’m going to expand this example to include blob storage and queues as well in the near future but at the moment, I’m just going to hit the Azure Tables.

update – here are the slides for the presentation:

To get started, I downloaded and installed the Zend Framework CE 1.10 and Zend Studio 8 Beta 2. Then I downloaded and installed the Windows Azure SDK. imageThe last bit that I needed was the Windows Azure 4 Eclipse which will install inside of Zend Studio since it’s built on Eclipse. To install it, open up Zend Studio/Eclipse and select Help | Install New Software to open up the dialog. Then click Add… and fill in the location as http://www.windowsazure4e.org/update. Click OK, select the Windows Azure for Eclipse Toolkit and follow the rest of the wizard to install it. At this point, I’ve got all of the software installed that I need to install and am ready to start coding.

Creating the Project

Before I create the project, a quick tip is that it’s a lot easier to work with IIS if you move the your Eclipse Workspace to c:\users\public\ZendWorkspace (I’m on Windows 7 so that’s where my public documents are). One more quick step is that I give IUSER Read and Execute permissions on the workspace.

imageOnce I’ve moved my workspace, in Zend Studio, select File, New Zend Framework Project.

Name the project SimpleCloudDemo.

Select “Create new project in Workspace”. I tried creating the project on a local server to skip a few steps but that didn’t work so well as you have to be an administrator to write to the c:\inetpub\wwwroot location. Instead, we’ll just map a virtual directory in IIS in a few moments.

Make sure that Zend Framework default project structure is selected (should be the default).

Click Finish. This will create basic project structure that you’ll need to get started. The Zend Framework is a MVC style framework.

To finish setting up the project we need to include the framework bits and the API bits so that we have everything in a nice portable folder. Copy in the C:\Program Files\Zend\ZendServer\GUI\library\Zend directory to [project dir]\library.

Lastly, download the SimpleCloud Api from http://simplecloud.org/download and unzip it to the [project dir]\library directory.

Mapping the IIS Virtual Directory

Now we want to be able to test and make sure that everything is installed correctly and that the project works. To do this, we’re going to map a IIS virtual directory.

image Open Internet Information Services (IIS) Manager and expand the tree on the left hand side until you find the default web site.

Right Click on the Default Web Site and select Add Virtual Directory…

Fill out the Alias with something simple to remember such as simpleclouddemo and fill in the Physical path with the directory to [your project directory]\public. Since I moved my workspace up above, the full Physical path that I entered is c:\users\Public\ZendWorkspace\SimpleCloudDemo\public

image Now, browse to the virtual directory at  http://localhost/simpleclouddemo.

The one other thing that I’ll do that’s IIS specific is create a URL_Redirect rule that will make sure that the Zend Framework actually gets all of the calls rather than the calls just going into the IIS bit bucket. The easiest way to do that is to create a file called web.config in the public directory.

<?xml version="1.0"?>
        <?rule name="Main URL Rewrite Rule" patternsyntax="Wildcard">
          <?match url="*" />
            <?add negate="true" input="{REQUEST_FILENAME}" matchtype="IsFile" />
            <?add negate="true" input="{REQUEST_FILENAME}" matchtype="IsDirectory" />
          <?action url="index.php" type="Rewrite" />

At this point you should have the project up and running. Now we’re ready to start slinging code.

Creating the Model and Azure Table

We’re going to dive right in and start creating the model and the Azure Table.

The first thing that we’re going to create is the Guestbook model class itself. Create a new PHP file named GuestBookModel.php in the /application/models directory as follows.

// application/models/GuestbookModel.php
class Application_Model_Guestbook extends Zend_Service_WindowsAzure_Storage_TableEntity
	* @azure comment Edm.String
	public $comment;	
	* @azure created Edm.String
	public $created;
	* @azure email Edm.String
	public $email;

Couple of things that are interesting here.

  1. Notice that the class extends (read inherits for those of you that don’t do PHP heavily) Zend_Service_WindowsAzure_Storage_TableEntity. This parent class gives us the other required fields such as a PartitionKey, RowKey, TimeStamp and the like.
  2. Next, notice the @azure comments in front of each of the variables. This gives typing information to the Azure Table storage engine for comparisons, sorting and storage optimization. The possible choices there are:
Property Type Details
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 UTC time. The supported range of values is 1/1/1601 to 12/31/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.

The next thing to do is create the GuestBookMapper in the application\models directory.

// application/models/GuestbookMapper.php
class Application_Model_GuestbookMapper
	protected $_cloudTable;
	protected $TABLE_NAME = "guestbook";
	protected $PARTITION_KEY = "guests";
    public function setCloudTable()
    	//This constructor takes account parameters for the live azure account
    	//Goes to Dev Storage if you don't pass in any parameters. 
    	$tableStorageClient = new Zend_Service_WindowsAzure_Storage_Table();
		$this->_cloudTable = $tableStorageClient;
        return $this;
    public function getTableStorageClient()
    	if (null == $this->_cloudTable) {
        return $this->_cloudTable;
    public function fetchAll()
    	$tableStorageClient = $this->getTableStorageClient();

        if ($tableStorageClient->tableExists($this->TABLE_NAME))
    		return $tableStorageClient->retrieveEntities($this->TABLE_NAME, "", "Application_Model_Guestbook");
    	return null;
    public function save(Application_Model_Guestbook $guestbook)
    	$tableStorageClient = $this->getTableStorageClient();
        if (!$tableStorageClient->tableExists($this->TABLE_NAME))
    	if ($guestbook->getRowKey() == null) {
    		$guestbook->setRowKey(uniqid ());
	$tableStorageClient->insertEntity($this->TABLE_NAME, $guestbook);

As you look at that code, there’s a couple of things to point out.

  1. I could pass in parameters to the constructor of the Zend_Service_WindowsAzure_Storage_Table constructor to give my account information for a Windows Azure storage account but if you don’t pass anything in it defaults to the dev storage account.
  2. In the fetchAll() function,  the second parameter being passed to the retrieveEntities function is a filter parameter. This is where you could pass in the search parameters and/or a partition to retrieve and so on. Regardless of what you pass in, the function attempts to match on those items and returns a collection of items that match.

The next thing is to create the GuestBookController.php in the application\controllers folder.

 * GuestbookController
 * @author
 * @version 
require_once 'Zend/Controller/Action.php';
class GuestbookController extends Zend_Controller_Action
     * The default action - show the home page
    public function indexAction ()
        $guestbook = new Application_Model_GuestbookMapper();
        $this->view->entries = $guestbook->fetchAll();
    public function signAction()
        $request = $this->getRequest();
        $form    = new Application_Form_Guestbook();
        if ($this->getRequest()->isPost()) {
            if ($form->isValid($request->getPost())) {
                $comment = new Application_Model_Guestbook();
                $comment->comment = $form->getValue("comment");
	       $comment->email = $form->getValue("email");
	       $mapper  = new Application_Model_GuestbookMapper();
                return $this->_helper->redirector('index');
        $this->view->form = $form;

Couple of things to point out here as well.

  1. In the indexAction, the fetchAll() call returns the list of entries as a collection and  hands it off to the view.
  2. In the signAction, we’re using the Application_Form_Guestbook which we are about to create. It’s got a little bit of validation but I wouldn’t rely on just that for my business logic but I’m a belt and suspenders kind of guy when it comes to data validation.

The next step is to create the Guestbook.php in application\forms directory.

class Application_Form_Guestbook extends Zend_Form
    public function init()
        // Set the method for the display form to POST
        // Add an email element
        $this->addElement('text', 'email', array(
            'label'      => 'Your email address:',
            'required'   => true,
            'filters'    => array('StringTrim'),
            'validators' => array(
        // Add the comment element
        $this->addElement('textarea', 'comment', array(
            'label'      => 'Please Comment:',
            'required'   => true,
            'validators' => array(
                array('validator' => 'StringLength', 'options' => array(0, 1000))
        // Add a captcha
        $this->addElement('captcha', 'captcha', array(
            'label'      => 'Please enter the 5 letters displayed below:',
            'required'   => true,
            'captcha'    => array(
                'captcha' => 'Figlet',
                'wordLen' => 5,
                'timeout' => 300
        // Add the submit button
        $this->addElement('submit', 'submit', array(
            'ignore'   => true,
            'label'    => 'Sign Guestbook',
        // And finally add some CSRF protection
        $this->addElement('hash', 'csrf', array(
            'ignore' => true,

The only thing to point out here is that this is a standard Zend Framework form.

The last thing that we absolutely need to do is create the two views, one for viewing and one for signing. The first one that we’ll create is index.phtml in application\views\scripts\Guestbook

<!-- application/views/scripts/guestbook/index.phtml -->
<p><a href="<?php echo $this->url(
'controller' => 'guestbook',
'action' => 'sign' ),
?>">Sign Our Guestbook</a></p> Guestbook Entries (<?php echo count($this->entries) ?>): <br /> <table>
<?php foreach ($this->entries as $entry): ?>
<td><?php echo $this->escape($entry->email)?></td>
<td><?php echo $this->escape($entry->comment)?></td>
<?php endforeach ?>

And next we’ll create the sign.phtml in application\views\scripts\Guestbook.

<?!-- application/views/scripts/guestbook/sign.phtml -->
Please use the form below to sign our guestbook!
echo $this->form;

There are other things that we could do but that all that we need to do for the moment. I’ll extend this example in the future.

Now, if you run the application and browse to http://localhost/simpleclouddemo/guestbook

If you get the error “Application errorexception ‘Zend_Http_Client_Adapter_Exception’ with message ‘Unable to Connect to tcp:// Error #10060: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.” – it’s because you need to launch the Development Fabric and specifically start the storage bit.

Once that’s done, you should see the guestbook as follows:


Then you can sign the guestbook as follows:


And then it will redirect you back the guestbook which will look as follows:


This is the bulk of what I demoed during the webinar. I’m going to continue to expand this demo as time goes on

Webinar on Oct 20, 2010 with Microsoft/Zend

imageI’m looking forward to starting this new webinar series that I’m launching in partnership with Zend about running PHP in general and Zend in particular on Microsoft Azure.

My goal, as I’m writing the demos today after posting this, is to go through the Zend Guestbook quick start and then port that to run in Azure and leverage that platform. I’ll be posting the full technical write-up here once I get done.

From the Zend web site:

Join a webinar on Cloud Computing with Zend Framework and Windows Azure. In this session, we’ll take a technical overview of Windows Azure Data Storage which can be used both inside and outside of your cloud application and the Windows Azure computing which can be leveraged to scale your application horizontally. We’ll write a small application with the Zend Framework and get it up and running in Azure so that we can dive deep into the individual parts in future webinars.
Join this webinar to learn how to take your application to the next level.


It’s important to note that this is the first of a series so we’re going to do an overview across the board this time and then we’ll dive deep into things such as the data access layers or architecting for scaling horizontally across multiple instances in the future.

Scaling WordPress on Microsoft

image I just finished doing a talk at OpenCa.mp in Dallas called “Scaling WordPress (and really any PHP application) on Microsoft. The reality is that there is a tremendous amount of support for WordPress on the Microsoft stack including Windows, IIS, SQL Server, Azure and more.

OpenCa.mp was a an interesting conference and interesting crowd for my session. The idea behind OpenCa.mp is to get all of the big CMS options under the same roof and cross pollinate. This included WordPress, Joomla! and Drupal from the PHP side of the house, DotNetNuke and SiteFinity from the .NET side of the house and Polux from the Python side of the house. It was an interesting mix. I was a little nervous that it would just be a giant argument. While some of that did happen, I actually had a few people from Drupal and Joomla! in my WordPress session and people were fairly civil the whole weekend. image

Getting to the session

Now, on to my session itself. This was a fun session. I only had 30 minutes and I had about 3 hours of material so I’ve got a ton of stuff in these notes that I didn’t cover in the session itself.

The session is a take off a session that I did at MODxpo back in the spring. The talk itself is about 3-5 minutes of slides and the rest is all demos. Really, there’s not time to do all of the demos that I’d like to do. I could spend 3-5 hours doing demos if they’d let me. I’d love to get up and sling a lot more code than I normally get to in a conference session and really dig deep on the tech side.

The slides are up on SlideShare but here at the talking points

imageThe most important slide in the deck is my contact slide which has my email address and such on it so that people can reach out to me with any questions.

I love getting follow up questions after a session because it proves to me that people were listening and not just hiding from the Texas heat in my room.

image Microsoft is a software company that builds a lot of great platforms and applications. We have a large number of finished applications such as Microsoft Word and so on that a ton of people use out of the box every day to accomplish their job. But one of the exciting parts about Microsoft is that almost everything starting with Windows, SQL Server and so on all the way up to Microsoft Office is also a platform that other people (read you in the audience) can write applications on top of in addition to just using out of the box. The conglomeration of platforms from Microsoft that I’m talking about today is Windows, IIS, SQL Server and Azure and running PHP/WordPress on top of those platforms.

Looking Back

image Before we get to that, however, we need to take a quick peek back in history. Many of you probably tried PHP on Windows at some point in the history so you’re thinking that I’m crazy to attempt PHP on Windows. The reality is that in the past you might have been right.

image 5 years ago, PHP did not run on Windows all that well. It was slow. PHP wasn’t optimized for Windows/IIS and Windows/IIS wasn’t optimized for PHP. Painfully slow at points.

image It wasn’t compatible with the other versions of PHP. If you were on Windows vs. Linux, you had to take that into account when you were writing your applications and there were standard switch blocks that you’d have to code in order to accommodate the different platforms. Most people didn’t bother doing that so there was platform lock in which defeats much of the purpose of running PHP.

image There wasn’t a good implementation of mod_rewrite or a good alternative. This cause all kinds of problems with SEO optimization and much more.

image There were many other problems and it just made the PHP developers (understandably) mad at Windows and Microsoft.

image So where are we now?

image Microsoft has invested a tremendous amount of time and resources into making sure that we fix all of those issues.

image PHP on Windows is fast. FastCGI support for IIS 7.0, 6.0, 5.11 rocks and is fast. It’s the default on IIS7 and it’s a fast and reliable way to run PHP on Windows. Additionally, there’s a fantastic opcode and object cache library called WinCache that is distributed with PECL. More on this in the demos.

There are all kinds of benchmarks out there but I’d like for you to test it yourself. There are many areas where PHP on Windows/IIS is just as fast or faster than PHP on Linux/Apache. There are other areas where performance suffers some. You should test your application on both platforms and compare performance. For some applications you’ll be pleased, for others you won’t be. Either way you’ll learn something about your application.

image PHP on Windows/IIS is compatible because it’s the same PHP. This means that most of the applications should just run on IIS. Where there are incompatibilities, it’s because there are some extensions and such to PHP that don’t run on IIS because they are deeply embedded in the Apache piping system or they leverage something in Linux and so on. In some cases there are compatible alternatives. In other cases, we’ll have to work around those. If you run into one of these cases – PLEASE reach out to me and let me know what you’re trying to accomplish.

image A great example of where we don’t have the exact same thing but a great alternative is mod_rewrite on Linux and URL Rewrite on IIS. I’ll walk through a demo of this in just a little bit but in short, URL Rewrite is a fantastic and powerful engine that allows you to do some outstanding things.

image More pigs fly – we didn’t stop there. In June 2009, we contributed 20k lines of source code to the Linux kernel to do much better virtualization support for things such as Suspend, Hibernate and Resume. Obviously our motivation was to get it to work better with Hyper-V but that code also helps with VMWare, Parallels and more.

Getting to the Demo

image Now, all of that is fantastic but let’s get to some demos. Demos are the meat of this talk.

image ‘Cause I think that you want to see what’s in my smokin toolbox here and seeing is believing.

Web Platform Installer

imageThe first thing I need to do is get WordPress up and running on my Windows installation. The easiest way to do that is with the Web Platform Installer. This is a free tool that Microsoft has put out there to make your life easier on IIS. You can, under the Web Platform Tab, configure your server to install modules such as URL Rewrite, Advanced Logging features, ODBC or any number of things that are optional on IIS but you might need to leverage.

But the tab that we’re most interested in is the Web Application tab where you can find WordPress. Under this tab you’ll find a bunch of different applications ranging from Aquia Drupal to DotNetNuke to Moodle to ScrewTurn Wiki to WordPress.

All of these applications and all of this data actually comes from the Web Application Gallery.

image If you select WordPress and click Install, you’ll get the installation wizard which will analyze the requirements for the applications and make sure that you have everything and download it if you don’t. An important thing to notice here is that the WordPress install is actually coming from http://wordpress.org/wordpress-2.9.2-IIS.zip. If you’ll notice, that’s actually coming from the WordPress foundation rather than from Microsoft. We’re not distributing WordPress or any of these projects. Instead, we are providing a channel and portal for those applications with a lot of support to make sure things are tested and ready to go.

image The next couple of screens that we see are configuring your specific installation. The first screen is a common screen that all of the projects get that has to do with were you’re going to put the physical files and the virtual directories stuff that IIS cares about. If you are running multiple web sites off of one machine, here’s where you make that assignment. For example, I’m running http://www.joshholmes.com and http://www.wonderpuzzle.com off of the same server

imageThe second page is actually configured by the project itself and has to do with the project’s configuration files directly. WordPress, for example, needs to know the MySQL Administrator’s password so that it can log into MySQL and create the database. It also needs to create a user for that database it set it’s password and the like. This is all part of the package that was downloaded from WordPress.org.

Investigating the WebPI Package

image That package is just a ZIP file with the PHP files, SQL Scripts and a couple of XML files in it. If you open the ZIP file and look at the parameters.xml file, you’ll see how this is all built up. For example, there’s a custom parameter called DbName with a default value of “wordpress” that’s got a regular expression validation of “^\w{1,16}$” or in English, 1 to 16 characters in length with no whitespace or punctuation. This parameter file is inserted into the install.sql file wherever the Web Platform Installer finds the word “PlaceholderForDbName” and in the wp-config.php file where if finds “putyourdbnamehere”. This makes it easy to set up any parameters that you want and insert them into any file that you want. And if you want, you can create your own projects and custom feeds for the Web Platform Installer to leverage. I’ll have to write an article about doing that in the near future.

The next thing that happens is that the install is done and you’re ready to start setting up your WordPress install. You should be, if you’ve ever set up WordPress on any platform, be familiar. You have to make sure that you copy that fantastic auto-generated password, log in and immediately change your password so that you don’t forget it.

An important thing to point out here is that even though it’s an older version of WordPress that’s installed, it’s still WordPress and WordPress can update itself and you should do that if you are going to run this for more than a quick demo.

Pretty URLS and URL Redirect

image The next thing that I want to do is set up my navigation and URL redirection. Just like any other WordPress install, you can do that under Settings | Permalinks. Select your favorite configuration and once you save your updates, there’s a prompt that tells you “You should update your web.config now”. If you’ve done this on Linux, you’ll get a prompt that says “You should update your ht.access now”. This is because URL Rewrite leverages the web.config. You can actually, if you’ve got an ht.access file that you use all the time, import that directly through the Internet Information Services Manager. The web.config is an XML file that has a tremendous amount of power. In this file you’re able to create file handler mappings, security settings on a per directory level, FastCGI settings, default documents for the application, IIS modules and a ton more. The web.config that WordPress requires at a minimum for pretty URLs is as follows:

<rule name=”wordpress” patternSyntax=”Wildcard”>
  <match url=”*” />
      <add input=”{REQUEST_FILENAME}” matchType=”IsFile” negate=”true” />
      <add input=”{REQUEST_FILENAME}” matchType=”IsDirectory” negate=”true” />
  <action type=”Rewrite” url=”index.php” />

Save this as a file called web.config in the root directory of your web application and you’re good to go with pretty URLs.

Quick Peek At WinCache

The next thing that I want to look at is WinCache. WinCache is a library written by Microsoft and distributed through the PECL Foundation. It’s a op code caching and object caching library that is on by default in the PHP install from the Web Platform Installer. To demo this I turned off WinCache in the php.ini file and used a little client app called WyCats that spins up 25 threads and starts hammering the server. It measures the number of requests, responses, errors and the like. Then I turn WinCache back on and restart WyCats. Immediately there’s a 3-4x improvement in performance. We could go a lot deeper with WinCache but that’s a topic for a different blog post.

Windows Azure Data Storage

This helps you scale vertically on a single box but to get true scale, we’re going to need to start leveraging horizontal scaling. One of the easy things to do is leverage a WordPress Plugin called “Windows Azure Storage for WordPress” which will offload the use generated media such as pictures, media files and anything else heavy to the Azure Data Storage which can be put out on the new Azure Content Delivery Network. That’s got a global footprint and helps you put your content near to your reader.

More WordPress Plugins that Rock

There are a lot of other WordPress plugins that leverage various parts of the Microsoft ecosystem including the Bing 404 plugin, the Bing Maps plugin, the Silverlight Streaming Media plugin and more. I’m pretty excited about all of these plugins.

  • The Bing 404 plugin handles broken links and will do a Bing search of your site suggesting possible updated links. This one was written by Cal Evans of Blue Parabola.
  • There are actually three different Bing Maps plugins. The Silverlight Bing Maps plugin is awesome, even if all of the comments are written in French. It helps you drop a Bing Map anywhere on your site with the use of shortcodes.
  • The Silverlight Streaming Media leverages the Smooth Streaming support in IIS to intelligently stream the media at the appropriate fidelity for your consumer based on their bandwidth,  machine specs and the like.

All of these plugins are obviously released under GPL since they are hosted on the WordPress.org site and easily found through the add new plugin search.

Windows Live Writer

One of the things that I didn’t plan on hitting on but decided to after I saw that there was a fair number of bloggers in the room that weren’t as technical is Windows Live Writer. It’s a free tool that allows you to do your blogging and posts in a desktop application so you can do it offline and have all of the richness of a desktop application. It’s got preview states where it will actually show your blog post as you’re writing it as it will look on the page complete with margins, your CSS and the whole nine yards. There are hundreds of fantastic plugins to do everything from inserting maps to formatting HTML code to managing flickr images.

It’s the tool that I use to do all of my blogging. This post, as an example, I wrote in three different airports, on two different planes and I’m in my hotel room at the moment finishing it up.

Between WordPress, Windows Live Writer and Jing, I’m a happy blogger.

SQL Server Support!

image Ok, back to the slides for a bit.

Another thing that’s very exciting is SQL Server support is available right now. This is not in core yet but we’re hoping that we can get it accepted at some point in the near future.

imageNot only that, but there’s a new PDO driver for SQL Server so that any code that leverages PDO (such as Drupal) can have SQL Server support if you’re using SQL statements that are supported by SQL Server. For example, if you’re using LIMIT statements as an integral part of your business logic, we’ll need to figure out a workaround.

Free Stuff

Now, if any of this interests you we’ve got a number of different offers to that fit a variety of options for getting you software, marketing support and more from Microsoft.

Before we even talk about the *Spark solutions, there are a ton of tools and applications that are free from Microsoft.

  • Web Platform Installer – I already talked about this a ton.
  • Visual Web Developer Express – This is a fantastic web dev toolkit that includes code editing, debugging support and more.
  • SQL Server Express 2008 – This is actually a really powerful option as a free database option. It supports up to a 10 gig database, transactions and the whole nine yards. The features that it doesn’t include are in the enterprise features such as Reporting Services and the like.
  • Windows Azure SDK for PHP – This fantastic SDK gives you access right in PHP to all of the Windows Azure Data Storage options and much more.

The list is actually REALLY long but this isn’t the focus of this blog post and I didn’t really spend a ton of time on it in my talk cause I didn’t have time.

DreamSpark is for Students. This gives you access to many of our professional tools and the like for you to leverage. There are also fantastic student discounts on Microsoft software for students. DreamSpark is completely free of charge.

WebsiteSpark is for small shop web consultants. The definition of that is anyone whose company is less than 10 people (yes – individual consultants count in this definition) and the company creates net new web sites for other people and companies. What this gives you is 3 copies of Visual Studio Pro and Expression Web, a copy of Expression Blend, production licenses for Windows Server and SQL Server Web Edition, entry into the Microsoft Pinpoint tools which drives business to local Microsoft partners and more. There are no upfront costs and at the end of three years, Microsoft will invoice you for $100.00. Other than that, it’s free of charge.

BizSpark is for technology startups. The definition of a technology startup for the purposes of this program is less than 3 years old, less than one million in revenue a year, privately held and creating software or software as a service. This gives the startup 25 licenses for MSDN which gives the developers pretty much any thing that they can build an application on top of. There’s also marketing support and such that can be leveraged through this program. There are no upfront costs and at the end of three years, Microsoft will invoice you for $100.00. Other than that, it’s free of charge.

I strongly encourage you to look at the various spark programs and see if there’s one that fits you.

More Azure Support

image Don’t know if you know this but OddlySpecific.com, which is running in Azure itself and leveraging the SQL Server support and the Azure Data Storage options with SQL Server. We’re working making that more broadly available so that sometime soon you could run in Azure as well. The awesome part about that is that it will allow you to scale up very quickly to meet market demands without having to think about infrastructure.

Lots of Resources

Web Platform Installer

How WinCache makes PHP run faster

Using WinCache Extensions for PHP

Changes Made to PHP 5.3 to Support Windows

Migrating from PHP 5.2.x to PHP 5.3.x

SQL Server PHP Blog

SQL Server Support for WordPress

Microsoft’s WordPress Site on VisitMix.com

Microsoft’s Official WordPress Landing Page

Josh Holmes’ Blog


To wrap up the talk and this blog post, PHP on Windows works really well and there’s lots of great support for all of the major PHP CMS/blogging engines including WordPress, Drupal and Joomla!.

I had a ton of fun at OpenCa.mp and hope to go back if they do it again next year. I’m hoping that next year I can do a full on hour of deep dive technical stuff that will really hit that ninja level that I wanted to cover. As you can tell, I brought way too much material but amazingly I actually hit my time mark perfect (I’ve been working on that).

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"?>
    <!-- DO NOT REMOVE: PHP FastCGI Module Handler -->
      <clear />
      <add name="PHP via FastCGI"
           scriptProcessor="c:\program files\php\php-cgi.exe"
           resourceType="Unspecified" />
      <!--add name="PHP via FastCGI"
           resourceType="Unspecified" /-->
      <add name="StaticFile" path="*" verb="*" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" resourceType="Either" requireAccess="Read" />
    <!-- Example WebRole IIS 7 Configation -->
        <clear />
        <add value="index.php" />

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.

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.

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 http://www.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.


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:

 * 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";

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(
    $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" />
<input name="posttitle" /><br />
<textarea rows="5" name="postdescription" type="text"></textarea><br />
<input name="postauthor" /><br />
Choose an image to upload:
<input type="file" name="imageUpload" /><br />
<br />
<input value="Create Post" type="submit" />

3. Create a new file called newpost.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))

$blobStorageClient = new Microsoft_WindowsAzure_Storage_Blob();
if (!$blobStorageClient->containerExists($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>
	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.

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:

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:

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(

	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>';


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 http://www.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 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.


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.

Easy Setup for PHP On Azure Development

I just got back from the JumpIn Camp in fantastic Zurich, Switzerland. I’ll blog about that whole experience shortly. In the meantime, however, I thought I’d get some resources out here that would have been useful last week. 🙂 Specifically in this post, I thought I’d tackle the Windows Azure 4 Eclipse tooling setup.

There are two major things that we need to do. First is to get the Windows Azure SDK installed. The reality is that this is all that you *really* need to do Windows Azure development and testing. However, we want to do our PHP development with the Eclipse toolset for Azure. This gives us debugging support and a lot of great helpers.

Installing the Windows Azure 1.1 February 2010 SDK

First, we need to get the requirements for the Windows Azure 1.1 February SDK itself installed.

To get started, we need to have Windows Vista with Service Pack 1 or later. Really, I recommend that you go with Windows 7 if you have to upgrade.

Enabling ASP.NET and CGI in Windows Features The next thing that you need is to enable IIS with ASP.NET and CGI support. This is easier than it might seem. In the Control Panel, find “Turn Windows Features on or off”. On Vista, you might have to open Add/Remove Programs to find that option. Here, you need to navigate down the tree and find Internet Information Services | World Wide Web Service | Application Development Features and enable ASP.NET and CGI. That will auto select the other dependencies such as .NET Extensibility and ISAPI Extensions and Filters.

Once you complete that, you need to install some version of SQL Server 2005 or later. The one that I recommend, if you don’t have SQL Server already installed is Microsoft SQL Server 2008 Express.

Those are all of requirements the Windows Azure 1.1 February 2010 SDK. At this point we can download and install it.

Installing Eclipse with the Windows Azure for Eclipse tooling

The next step is to install Eclipse itself. Eclipse is written in Java so you will need the Java JRE 5 or later. 5 is no longer supported so I recommend that you go with Java JRE Standard Edition Version 6.

Once that’s installed, it’s a simple matter of downloading the PDT 2.1 All In Ones / Eclipse PHP Package and unzipping it into a folder. The PDT version of Eclipse comes with a lot of tools for PHP including perspectives for PHP, the Zend debugger, XDebug, syntax highlighting and more. The Windows Azure 4 Eclipse tooling builds on this.

Now, you need to install the Windows Azure 4 Eclipse tooling. To do that, open Eclipse and select Help | Install New Software. Click “Add” and put in Windows Azure For Eclipse for the title and http://www.windowsazure4e.org/update for the location. In the tree below, select all three pieces and follow the rest of the wizard.


This installs the Windows Azure for PHP SDK and a lot of tooling inside of Eclipse to get you set up.

At this point, you are technically ready to go but I recommend doing a few more things.

Quick Tips to Make Things Smoother

There are a number of little things that we discovered throughout the week that will make things easier for you.

PHP Version Conflicts

The first thing to do is to check to see if you’re going to have any conflicts between the version of PHP on your disk and the version of PHP that comes with the Eclipse tooling. The conflict is that even if both versions are PHP 5.2.13, the version that Eclipse uses is the thread-safe version and the one that everyone else in the world uses is the non-thread-safe version because most people don’t do threading in PHP anyways (I know you do Liz Smith but you’re not most people…). This happens if you’ve used the PHP Installer or the Web Platform Installer to get PHP on your box because both of them put PHP in the %Path% which is the right thing to do. The issue comes in when the Azure DevFabric starts PHP-CGI.exe from your Azure install but that executable looks in the path for it’s dependencies. It finds the non-thread-safe libraries and throws an exception. Oops.

*update* I had a much better idea than the below – check out my new post on resolving the PHP Version conflicts at Resolving PHP Version Conflicts While Developing For Azure”

There are a couple of fixes that you could leverage, none of which are ideal. One is to just install the thread-safe version on your box. There are two issues here. First is that you are now using the thread-safe version of PHP on your own box and it might not be that one in the cloud. The second issue is that you are using your php.ini file from the c:\Program Files (x86)\PHP\ folder. This is not really an issue if you remember this fact and make sure that you deploy that PHP.ini file and set of extensions that you want to deploy.

The other fix, the one that I’ve chosen to do most of the time, is to simply rename the PHP directory on my disk (typically at c:\Program Files\PHP or c:\Program Files (x86)\PHP) when I’m doing Azure development and rename it back when I want to do local development. This is a little bit of a pain sometimes but it’s easier to find these issues than the subtle ones that could be introduced by the other technique.

Resolving the mystery 500 Error

Unfortunately, there’s not a great way to divine what is causing the 500 error in some cases. The one that I see most often is the PHP version conflict. Others include database connection errors, file permissions issues, uncaught exceptions and the like. There are two ways to handle this.

The first is to make heavy use of the logging facilities to write out to the dev fabric manager’s UI the exception.

The second way is to attach either the Zend debugger or XDebug to the Dev Fabric and step through the issue. The way to do that is to

Zend Debugger and Windows Azure DevFabric Storage

Changing the Zend Debugging PortThe first thing is that the Windows Azure DevFabric Storage uses port 10000. This is not a bad thing except that the Zend Debugger, by default, also uses port 10000. The end result is if you launch Eclipse and then try to start the development fabric storage engine, you’ll get a conflict.

Specifically, the error is from the Development Storage engine – “The process cannot access the file because it is being used by another process”. This is a bizarre error that doesn’t actually give you correct information. The way to fix this is in Eclipse, go to Windows | Preferences, find the Zend Debugger settings and edit the port.

Download Windows Azure for PHP Contrib Project

There are a couple of things that are not in the Windows Azure for PHP SDK. A couple of specific examples are Azure Drives, editing the PHP.ini and more. That’s all found in the Windows Azure for PHP Contrib project by Maarten Balliauw. Fun story on this is that at JumpIn Camp Maarten looked over at me and asked me if there was a way to mount Azure drives in PHP. I said that I didn’t think so. 20 minutes later, he called me over to show me that he had gotten it working. He spent another 20 minutes cleaning it up and committed his patch to the Windows Azure for PHP Contrib

Creating a Hello World Azure Application with Eclipse

Select Windows Azure Web Project This has walked you through the setup of the Windows Azure 4 Eclipse tooling and now you’re ready to get started with your first Azure application to test the install and all.

To test the install, click File | New | Project. In the New Project Wizard, expand the tree to find PHP | Windows Azure Web Project.

Click Next.

PHP Azure Project WizardIn the PHP Azure Project, name the project Hello World and select the Windows Azure Data Storage option.

Click Finish.

This will create the project and give you some starter code that you can work with. To do that, select the project in the PHP Explorer and select from the menu Windows Azure | Run in Development Fabric. This will package the application and then launch it in the DevFabric. If it’s not running, it will give you the user access control admin permissions screen twice, once for the DevFabric Compute and once for the DevFabric Storage.

PHP InfoNext will launch the browser and navigate to your application running in the DevFabric. The simple Hello World show PHPInfo().

Soon, I’ll post about writing a slightly more complex application.

Please use the comments on this post to let me know if you were successful or not in getting the PHPInfo() to show…

PHP On Azure Resources

I’m at JumpIn Camp in Zurich and we’ve been diving deep into PHP on Azure. One of the things that we’ve done is talk about a ton of resources that are available out there on the web to learn more about PHP on Azure. To that end, I thought I’d collect a few of them here on my blog.

In the morning, I talked at a high level about what Azure is, how the various roles work and how to run PHP on Azure. My deck that I used was the first half of the same deck that I used on the PHP On Azure World Tour.

Another great starting point and set of resources is Maarten Balliauw’s Blog itself. He’s been helping out here at JumpIn Camp from a technical perspective on Azure and running PHP on Windows in the first place. He did the next part of the session diving deep into the PHP on Azure SDK.

You’ll notice some overlap between our desk because we’re largely talking about the same SDK and leveraging the same code examples.

Maarten’s first deck that he used to talk about Blog, Queue and Table storage is:

The second one that Maarten used to talk about SQL Azure is:

Maarten also did a demo of an app called ImageCloud leverages both a Web and Worker role to do front end uploading of an image and backend processing of that image. That code can be found at ImageCloud Azure Demo Application.

For some great resources on architecture guidance, take a look at Windows Azure Architecture Guidance. This is put out by the Patterns and Practices group at Microsoft.


Another great resource is Benchmarking and Guidance for Windows Azure. This was created and launched by the Extreme Computing Group (aka XCG).


More resources:

Microsoft Windows Azure Interop

Microsoft Interop Bridges

Windows Azure 4 Eclipse


Windows Azure MySQL PHP Solution Accelerator


I’ll be adding to these resources over the course of the week so check back for lots more.

Making PHP faster on IIS

I’ve been doing quite a bit of work with PHP on the Microsoft stack recently. That includes my work with PHP on Azure and moving my blog to WordPress. I’ll be honest though and say that I’m simply standing on the shoulders of giants. The PHP on IIS team, including Ruslan Yakushev, the Web Application Gallery team, including Faith Allington, Crystal Hoyer and Mai-lan Tomsen Bukovec (all three of whom I wish would start blogging), the Microsoft Web marketing team (who happen to be extremely technical and are a credit to marketers everywhere), including Mark Brown, the Microsoft Open Source Technology Center (OSTC).

An example of this is that when I spoke at WordCamp Ireland, I talked about the amazing improvements in FastCGI over the past few years, the Web Application Gallery and Web Platform Installer (WebPI), URL Redirect, WinCache and many other things that Microsoft is doing to embrace open source technologies. My slides are below:

Now you can hear about these improvements from Ruslan Yakushev and Mark Brown themselves talking about these improvements, specifically the ones related to performance, with the good folks over at PHP Architect on a webcast…

For all the details, check out the web cast at Making PHP faster on IIS!

PHP on Azure World Tour

IMG_2837I have the privilege and honor of doing a tour of across Europe talking to PHP developers about running on Azure and on IIS. The countries that I ended up in are Ireland, Portugal, Austria, UK, Norway, The Netherlands, Belgium and then I went back to Ireland. That included 2 conferences and 6 Microsoft run events.

The way that the trip came about is that I was invited to keynote PHPUK 2010 and since I was going to be in Europe already, Beat Schwegler organized for me to visit the other countries. Big thanks out to him for organizing the whole trip.

The topic in at the Microsoft run events was “Scaling Big While Sleeping Well” which is a talk about PHP on Azure.

Dublin, Ireland (First time around)

Ireland was the first place that I did my Azure session. There were roughly 20 people in the audience.

Lisbon, Portugal

IMG_1966One of my regrets about the whole trip was that I didn’t get to spend as much time in each of the countries as I would like to have. Portugal was definitely one of them that I was disappointed that I didn’t get to spend more time in. I was on the ground for about 18 hours from 10:30 on Monday night to about 2:00 on Tuesday.

On the plus side, we had quite a few people in the audience and they were engaged. I had a ton of good questions and hopefully I answered them all. Also, it was a fantastic venue. It was in the new library building for one of the local colleges – Faculdade Nova de Lisbon. The venue was a real tribute to the college as it was a gorgeous facility and the room was almost acoustically perfect.

Vienna, Austria

IMG_2000This was my first time in Austria. My brother and sister both have done college studies in Austria so told me lots of different things to do while I was there. I was a little disappointed in the turn out at this event as it was only about 7 people there including Rolf Mistelbacher and Gerhard Goeschl from Microsoft.

Another cool thing in Vienna was that I got to catch up with an old friend Andreas Erlacher who showed me around downtown Vienna.

PHPUK 2010 in London, UK


One of the extremely cool things that I got to do is keynote at PHPUK 2010. I did my Lost Art of Simplicity talk as an uncon session at ZendCon. Scott MacVicor heard about it and was kind enough to pitch it to the board of the conference. The session went over really well and got a lot of great feedback on Joind.in – in fact it’s currently the most reviewed talk on Joind.in. 🙂 Considering that there were roughly 450 people in the audience and 500 at the overall event, it makes a lot of sense.

I want to thank Johanna Cherry, Matt Raines and the rest of the organizing committee for their organization and hospitality.

image Since I was doing the keynote, it didn’t really make sense for me to do another session as well. Rob Allen, however, stepped up big and did a session on Azure. Turns out that he had not looked at Azure prior to Will Coleman and I asking him if he’d be interested in doing the talk. Not only did he say yes, he did a fantastic job as well. I was also pleasantly surprised that there 52 people in the room to hear about Azure.

You can download Rob Allen’s Azure Slides.

Oslo, Norway

IMG_2825This was the first time that I had been to Norway. I got really lucky with the weather. Evidently the week before I was there it was –18 Celsius but it was –4 (roughly 25 Fahrenheit) which is actually a lot like how I left Michigan.

There were 12 people in the audience + Rune Zakariassen who was gracious enough to host me for the day. I also had a chance to meet with Petter Merok, the Developer and Platform Evangelism lead for Norway.

Amsterdam, Netherlands

IMG_2873I’ve been through Schiphol in Amsterdam a lot of times but not really gotten to spend much time outside of the airport itself. Also, it was fantastic to have a great guide around Amsterdam in Juliette Folmer.

The session itself was a joint meeting hosted by Microsoft and PHP Benelux. PHP Benelux is a cooperation of the Netherlands, Belgium and Luxemburg PHP user groups. Big thanks to Stefan Koopmanschap aka @skoop and Bram Veenhof for organizing in the Netherlands. There were two presentations. First was Jan-Willem Eshuis from NOS. NOS is a public broadcast network in the Netherlands that manages all of the sports broadcasting in the country. He talked about Service Oriented Architecture and how NOS has been able to reach the scale that they have. It was a lot of fun talking with him about how they were managing and broadcasting the Olympic coverage. The second presentation was mine. It was a small group, 5 people, but they were very engaged and I almost didn’t make it through the materials…

Brussels, Belgium

IMG_2999I met with the Belgium branch of the PHP Benelux user group the next day in Brussels. This was another small but great meeting.

As with the previous meeting, there were two sessions. The first session was by Michelangelo van Dam aka @dragonbe. He took one of the Zend Framework sample applications and ported it from Linux to Windows showing how easy this process can be. This was cool because it gave between the two of us we were able to point out the power of the web.config from showing off simple configuration and setting up the FastCGI handler to showing the URL Redirect bits.

Next I talked about Azure. Here I got my my personal favorite compliment of the whole trip. It came from a hoster who came in hoping that he wouldn’t like Azure as it’s in direct competition with his business. He begrudgingly told me after the meeting that he was impressed and liked what he had seen. 🙂

Big thanks to Katrien de Grave for hosting me all day and organizing the meeting. It was also great to get to finally meet her after thousands of emails back and forth on various topics.

WordCamp Ireland in Kilkenny, Ireland

I wrapped up my tour by hitting WordCamp Ireland in Kilkenny, Ireland. Read all about that in my post about WordCamp Ireland.


I had a ton of fun on my tour even though it exhausted me completely.