Download in PDF
  1. Abstract
  2. Introduction
  3. Background
  4. Deploying and Running MoodleAzure
  5. Packaging, Configuring and Deploying the Solution
  6. Implementation Details: What Changed
  7. Horizontally Scaling the Application
  8. Conclusion


Before we get started, we must first understand the differences between running a PHP web application on a regular web server such as IIS or Apache, and running an application on Azure. In regular web servers, configuration settings usually point to paths on a local hard drive, file uploads are usually stored in a local directory structure, and session data usually resides in an OS-specific temporary path. In Windows Azure there is nothing preventing the application from creating temporary files, but there is also no such thing as a predictable hard drive letter mapping. All of the temporary files written by the application instance are not guaranteed to be persisted indefinitely. In other words, all files written to the “role’s disk” are volatile. This is why we need to move away from writing files to local hard drives, and use Windows Azure Storage Services.

Windows Azure provides various means of persisting data in a scalable manner. We will focus on using Windows Azure Table Storage and Windows Azure Blob Storage services. These services are simple, REST-based services used to write data that is guaranteed to be persisted across time. If you are a seasoned PHP developer, you probably know that session data is usually stored in temporary files. In Windows Azure we will be using the Table Storage service instead of temporary files. The good news is that, there is a good library that you can effortlessly use to move session persistence to Azure’s Table Storage service. Please refer to to download the Windows Azure SDK for PHP. We will cover the specifics on configuring your PHP application to use Azure’s Table Storage service for session persistence in a further section of this article. The bad news is that even though the Windows Azure SDK for PHP does have a custom stream wrapper, some advanced file operations required by a number of PHP applications are not compatible with the previously mentioned library’s stream wrapper implementation. To complicate things, some PHP applications rely on multi-level directory structures which, Azure’s Blob Storage service does not natively support. For these reasons, we had to modify the library in the SDK. This modified version provides:

  • Support for OS-level file system functionality and
  • Simulation of directory structures as blob name prefixes.

Another problem we face is the careful modification of the “php.ini” file for which we must keep in mind that paths cannot point to a local hard drive anymore. Configuration sections (such as the “extensions” section) which, heavily rely on path configuration entries, should now point to paths within the role’s root path. Again, we will walk through the specifics in a further section of the article.

Finally, the last issue that we need addressed could be the largest, or the smallest of our problems, depending on the situation. Typically PHP applications fall within the following scenarios:

a.       The web application uses MySQL as a database engine.

b.      The web application is designed to use MSSQL as a database engine. The use of the older “php_mssql” PHP extension instead of the newer “php_sqlsrv” extension is common.

c.       The application uses a database abstraction library such as ADOdb or PDO, which allows us to either write a new provider, or load a compatible extension.

For scenario a, we have 2 options: Load up MySQL in an Azure worker role, or migrate the data access code to use MSSQL with the “php_sqlsrv” driver. There are plenty of articles that show you how to run MySQL in a worker role. This approach is inconvenient, however, because you have to pay $0.12 an hour per worker role. That means you will end up paying $86.40 a month for a single instance of MySQL. And if you want to add failover support, you will need to create a second instance of MySQL in a worker role and configure it differently (i.e. as a slave). When comparing the work involved to deploy and maintain, and administer at least 2 MySQL instances in Azure worker roles, SQL Azure proves more convenient and far superior because you get a highly reliable, fast, and scalable 1GB database for only $9.99 a month. In short, it is strongly advised not to deploy MySQL in Windows Azure unless absolutely necessary, or until you have completely implemented SQL Server support for your application. Please refer to to get all the information you need about deploying MySQL on Windows Azure.

In scenario b, we encounter a typical situation in which an application has been developed with SQL Server as a database engine, but it relies on the “php_mssql” extension. The problem is that the “php_mssql” extension is not compatible with SQL Azure. You will need to re-implement SQL Server support on top of a different extension called “php_sqlsrv”. You can download the latest binaries from There are numerous differences between the 2 extensions, especially when it comes to parameter-binding and query execution. Also, method names are different. In other words, even if you are using the same database engine, migrating application code to support the “php_sqlsrv” extension is not as straightforward as loading up a different PHP extension.

Scenario c is what we encounter in more mature, well-architected applications. A database-agnostic library provides access to a number of different database server technologies and it is only a matter of implementing support (if not already there) for the “php_sqlsrv” extension. For older libraries such as ADOdb this task might prove challenging and time-consuming. In this article, we will provide a practical example of modifying, configuring, and packaging an existing PHP web application in this scenario – Moodle – in order to enable horizontal scalability, high availability and high performance using Windows Azure as a cloud computing platform.

Last edited Oct 28, 2010 at 4:37 PM by unosquare, version 5


No comments yet.