Windows Azure & PHP (for nubs)–Part 2 of 4
Ok, took a bit longer to get back to this than planned, but we’re here. So lets get stated.
In part one of this series, I talked about the tooling and getting a simple test app running in Windows. In this edition, we’ll take that to the next step and make it a Windows Azure web role and get that deployed to the local development emulator.
Unlike the previous Eclipse toolkit I had used, the new Windows Azure SDK for PHP is entirely command line based. This will be a bit of a shock of those of you used to the integrated experience offered by Visual Studio. But for those familiar with powershell and heaven forbid, older devs like me that used to get by on PERL or KornShell, it’s a pretty comfortable place to be.
This command line centers around the use of scaffolds, or templates. You can use the bare bones, default template, or if you’re more ambitious, create your own custom scaffolds. I’ll leave the topic of creating custom templates to those more experienced (and interested). So lets just focus on the default template in the SDK and what is gives us.
Ben Lobaugh of Microsoft has a great set of tutorials over at the interoperability bridges site, including one on setting up your first Windows Azure and PHP project. As this points out, to create our first, bare bones app we just open up the command prompt and type this:
scaffolder run -out="C:\temp\WindowsAzurePHPApp"
This creates an initial project at the location provided and by default it’s a Windows Azure web role. Ben’s tutorial also breaks down the contents of that location (the solution files, subdirectories, etc…). But lets look at that command a bit closer.
The “scaffolder” utility has two commands, ‘run’ which executes a scaffold (or template) and ‘build’ which is used to create a new scaffold (again, we’re going skip creating a custom scaffold). The ‘run’ command supports two parameters, –OutputPath (aka –Out) and –Scaffolder (aka –s). We specified the out location and since we didn’t specify a scaffolder, it used the default “Scaffolders/DefaultScaffolder.phar” which sits just under where the scaffolder program sits (which on my machine is C:\Program Files\Windows Azure SDK for PHP). At least that’s what the’scaffolder’ command’s help tells us. But that’s not the entire story. The DefaultScaffolder.phar file is really just a php script, and it defines additional parameters (you can open it with the text editor of your choice).
For example, take this comment block from that phar file:
* Runs a scaffolder and creates a Windows Azure project structure which can be customized before packaging.
* @command-name Run
* @command-description Runs the scaffolder.
* @command-parameter-for $scaffolderFile Argv –Phar Required. The scaffolder Phar file path. This is injected automatically.
* @command-parameter-for $rootPath Argv|ConfigFile –OutputPath|-out Required. The path to create the Windows Azure project structure. This is injected automatically.
* @command-parameter-for $diagnosticsConnectionString Argv|ConfigFile|Env –DiagnosticsConnectionString|-d Optional. The diagnostics connection string. This defaults to development storage.
* @command-parameter-for $webRoleNames Argv|ConfigFile|Env –WebRoles|-web Optional. A comma-separated list of names for web roles to create when scaffolding. Set this value to an empty parameter to skip creating a web role.
* @command-parameter-for $workerRoleNames Argv|ConfigFile|Env –WorkerRoles|-workers Optional. A comma-separated list of names for worker roles to create when scaffolding.
We see in this parameters such as “-WebRoles”, “-WorkerRoles”, and even “-DiagnosticsConnectionString” (along with short names for each). And if we go look at this tutorial by Brian Swan
(another great Windows Azure and PHP resource), you can see him using some of these parameters.
So what we see here is that the scaffolder can be used to quickly create various project templates for us. And if we customize the scaffolds (the php archive or .phar files), we can tailor them for our own unique needs. Powerful, if you don’t mind doing some scripting of your own.
Putting the “Azure” in
Alright, back to the bare bones sample project we created. We can easily put the same “phpinfo();” command into it, but that does us nothing. At least in a “Windows Azure” sense. What we really want to do is start leveraging the “Windows Azure” part of the SDK to put some cloud flavor into it.
First off, we need to locate the SDK location. In my case, its “C:\Program Files\Windows Azure SDK for PHP”. From there we go down a level into the “library” folder and copy the “Microsoft” folder from that location. We don’t HAVE to copy everything in the Microsoft folder, but I’d rather not get drug down into mapping dependencies just yet. Suffice to say that that this location contains all the php include files and binary proxies we need to interact with most areas of the Windows Azure platform.
The root of these files AutoLoader.php, which helps resolve class names at runtime. This also helps remove the need for you as a developer to juggle lots of includes. If we drill down into the WindowsAzure folder, we’ll also find items like a SessionHandler, a proxy class for RoleEnvironment, and sub-libraries for things like Azure Storage.
But I digress, we’re going to copy the Microsoft folder into our sample web role. I put this file right into the .Web folder, same place my default index.php and Web.config files are located. I then update my index.php file to look like this:
$val = Microsoft_WindowsAzure_RoleEnvironment::isAvailable();
echo "in environment";
echo "not in environment";
What this is doing is referencing the AutoLoader, using it to pull in a reference to the SDK’s RoleEnvironment class, and calling a static method of that class, isAvailable, to determine if we are running in the Windows Azure environment or not. Now at this point we could load the site using the virtual directory we created last night, or we could deploy the project to local Windows Azure development emulator with a command like this:
package create -in="C:\temp\WindowsAzurePHPApp" -out="C:\temp\WindowsAzurePHPApp\build" -dev=true
This command uses the “package” program of the SDK to create a cloud service deployment package for Windows Azure using the project files at the location specified by the ‘-in’ parameter. Then, by specifying ‘-dev=true’, we tell the utility to deploy that package to the Windows Azure development fabric. If we load out index.php file from the resulting URI, we should (hopefully, see note below) see that we’re now running in the Windows Azure environment.
|Note: isAvailable does not always work properly in the local development emulator. It appears to be a bug that creeps up occasionally but is difficult to reproduce. It can also change from fixed to broken depending on the version of the emulator you’re using.
Some debugging tips
Now if you’re like me and bit of a php nub (and you likely are if you’re reading this), you’re going to have some php parser errors when working up this sample. PHP syntax is so close to C# .NET that it is easy to mis-type things when moving back and forth between the languages. When this happens, you’ll get a blank page. The reason for this is that by default PHP doesn’t display detailed errors to help protect your sites. Detailed error messages can provide information that could make it easier for people to hack into a web site.
So the first thing we need to do is locate the php.ini file that controls this setting. The easiest way to do this (thanks for this tip Maarten), is to create a page that has “phpinfo();” in it and then load it. Check the “Loaded Configuration File” location and that will show you which file you need to update. Open it with your favorite text editor and track down the “display_errors” setting and set it from “off” to “on”.
Now this change only impacts your local environment. If you look at the template project you created using the scaffold, it includes a php folder with a php.ini file already in it. Its fairly bare bones, but this file will be used when you deploy your project to Windows Azure. So any tweak you make to the way PHP is configured for your solution , need to be added to this file as well if you want then to be applied when its deployed out to the Microsoft datacenters.
And next time on Script Adventures
So that’s it for part 2. Next time, we’ll explore the deployment process and what happens inside Windows Azure. If I’m lucky, I’ll even be able to show you how to setup remote desktop so we can peak into the virtual machine hosting our application and look at how the deployment process was executed.