Rev it up with PHP and IIS

Slide1_thumb[1]Mark Brown and I did a talk at ZendCon last week on how well PHP runs in IIS and more specifically, some things that you should do in order to make it run really well on IIS.

Quick warning, this is an unfortunately bullet pointy slide deck for me. Mark created the original deck that this talk was born from but I’m responsible for delivering it at ZendCon and for posting it here. 🙂

Mark is with the Web Platform Team and a good guy to know. He saved my tail on this one. My voice was killing me and he stepped in and did 80% of the talking. I talked through the demos but he hit all of the talking points.

Slide2_thumb[1]

We started the talk off with a little walk down memory lane. The reality is that many people who have tried PHP on Windows and really didn’t like it did so on previous version of IIS under CGI. Issue was that PHP on older version of IIS with the old school CGI handler It wasn’t until 2007 when FastCGI came out that things started to get interesting on the IIS stack.

Slide3

IIS 7 came out starting with Win7 and SQL Server 2008. It’s gotten a huge overhaul, not just in terms of PHP but terms of it’s entire architecture. To start with, the attack surface is greatly reduced as it does a very lightweight install and then you have to turn on anything that you want to run. Out of the box, it only serves up static files and you have to turn on ASP.NET, PHP and anything else.

The new modular architecture is fantastic. It used to be that you had to write any extension or modules in C++ or at least do a C++ wrapper around managed code. Now you can write your modules in .NET and load them directly. These modules can plug into any point along the processing pipeline and do anything from handling authentication to manipulating the incoming or outgoing streams.

Additionally the per application configuration has gotten tremendously powerful and can do anything from setting up the cache handing to URL Rewrite rules (more on this in a bit) to setting up the modules and handlers that can plug into the IIS processing pipeline.

Slide4Another great improvement is FastCGI. If you are doing PHP on IIS, you need to be using FastCGI. It is the CGI handler on IIS 7 and is available as a download for IIS 6. There were some really fundamental changes that were made. One of these is that under CGI, IIS spun up a new process for every request. This is a really expensive thing to do. Under FastCGI, it does some awesome things where it spins up a configurable number of processes and then recycles those same processes over and over again. There’s a ton of other great improvements here including recycling the PHP pool when the php.ini changes so you don’t have to manually restart IIS and much more.Slide5

WinCache is not installed by default on some IIS instances but you should check to make sure that it is. It’s distributed through Pecl at http://pecl.php.net/package/WinCache. It provides a ton of great enhancements including Opcode Cache, File Cache, Relative File Path Cache, Session Cache and User Data Cache. The awesome part is that all you have to do to take advantage of the first 3 is enable WinCache in your PHP.ini file. Just doing this has shown anywhere from a 100% to a 400% increase in performance depending on the application and what it’s doing.

To take advantage of User Data Cache, you need to write a little bit of code but all of the functions have the same function signature as APC. See the little bit of code that had to be written for Joomla support for WinCache for an example.

Once you’ve installed it, there’s a great script that will help show you what’s in WinCache at any given point – more details at http://blogs.iis.net/donraman/archive/2009/10/20/wincache-1-0-rc-using-the-statistics-page.aspx

Slide6

URL Rewrite is a very powerful rewrite engine for IIS 7 so you no longer have to look at external rewrite engines such as ISAPI Rewrite. Remember that this is not installed by default as IIS 7 installs with the smallest set of features possible. If you’re an Apache user right now, the easiest way to get started is to simply import your .htaccess file and it will pull in and convert your rules to the web.config file that IIS 7 uses.

One quick example is the one that I use for WordPress to enable pretty urls.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webserver>
    <rewrite>
      <rules>
        <rule name="wordpress" patternsyntax="Wildcard">
          <match url="*" />
          <conditions>
            <add negate="true" 
                 input="{REQUEST_FILENAME}" matchtype="IsFile" />
            <add negate="true" 
                 input="{REQUEST_FILENAME}" matchtype="IsDirectory" />
          </conditions>
          <action url="index.php" type="Rewrite" />
        </rule>
      </rules>
    </rewrite>
  </system.webserver>
</configuration>

But it can do much more than just dealing with simple redirection. It can match on wildcards, regular expressions and a ton more.

Slide7Another way to squeeze some performance out of PHP on Windows is to migrate to PHP 5.3. The builds of PHP 5.2 and previous for Windows are built with VC6 which is a 10 year old compiler. The new PHP 5.3 builds are built with VC9 which is a modern compiler with a lot of great optimizations. In addition, earlier versions of PHP on Windows did almost everything through a POSIX translation layer just to get it to work. The Windows support in PHP 5.3 has been rewritten to run natively on the Win32 APIs rather than having to go through the translation layer.

Now, if you really need to check out building your own Performance Guided Optimization build of PHP specifically for your box.

Slide8

The next thing look at is the new PHP Manager released on CodePlex. The very short version is that it allows you to run different versions of PHP on the same server for different applications. It manages  the php.ini file and PHP extensions per application as well. You can even connect to it remotely through the IIS Remote Administration Tool so you no longer have to have write permissions on the PHP directory on the box to manage things.

Slide9

Connecting to SQL Server has been a pain point as well for many years. In 2008, however, the SQL Server team released the new native drivers for PHP on Windows. Then this year (2010 for those those that are reading this later… 🙂 ), the SQL Server team released PDO support for PHP on Windows. Drupal 7 is actually already tested against this and ready to go.

The question was raised about when we’ll have Linux drivers for SQL Server and I’ll give the same answer here that I gave on stage. The SQL Server team has received that feedback and it’s on the radar. I don’t have any insight into the SQL Server team’s roadmaps or future plans and I have no idea if it will ever happen or when it would happen if it were on a roadmap somewhere but I do know that the SQL Server team has heard that request from multiple sources and they listen to their community. Is that non-answer enough for you? 🙂

Slide10

Another really useful utility is the IIS Database Manager. The easiest way to install this is through the Web Platform Installer. This plugin to IIS Manager helps you manage your databases whether they are SQL Server or MySql. It actually looks in your web.config file for connection strings and will show those databases in the “quick open” area or you can browse to your database and open it specifically. This is not going to replace your favorite DBA tool but it will give you quick and easy access to do simple things remotely without having to crack open extra ports and all that.

Slide11

Many of the most popular PHP apps out there run really well on IIS and are easily installed through the Web Application Gallery and the Web Platform Installer.

Get WordPress

Get Joomla!

Get Drupal

But don’t stop there, you can check out all of the applications in the app gallery until you find the ones that make the most sense for you.

Slide12

In addition to all the work on the core language and getting it to run really well, Microsoft’s been working hard at making things like SQL Server reporting services work with the SQL Server Reporting Services SDK for PHP. PHP works really well with Silverlight as Silverlight does a great job with restful services as well as having the best video experience out there through the adaptive streaming technology. I was talking to a PHP developer at ZendCon who does a lot of video and his shop used to have to buy 5 or 6 different bit rate videos to cover the different bit rates that their clients needed and they had to store all of that video somewhere. Now with Silverlight, they buy one video and store one video and all of their clients are shown the correct bit rate for their connection.

Slide13

We’ve been doing a ton with the PHP community. Many of the things that we talked about in this talk are out there at open source.

WinCache is on PECL and licensed under BSD.

WinCache support for Joomla! which we write is released under GPL 2.

SQL Server Driver for PHP is under Apache 2.0

I’m not going to drain the list but most of the work by the Interoperability Bridges team is released as open source.

We listen and interact on the PHP forums. Many of us can be found on IRC. We work with core team members from PHP and many of the top applications to help decide what are our next features, products and more. It’s been a really exciting ride the last 3-5 years here at Microsoft in the PHP and open source space.

Slide14

The quickest and easiest way to get started with PHP on IIS is through the Web Platform Installer. This wizard style installer will let you pick an application and not only install that application but it will determine what the dependencies are for it, configure your web platform and install all of those dependencies. And it’s language neutral installing both ASP.NET and PHP applications easily.

Slide15

In summary, PHP on IIS has come a long way in 5 years. It’s a viable choice not only for development but for production. Performance, stability, configurability and more have all improved dramatically through technologies such as FastCGI, WinCache, SQL Server and very importantly IIS 7. Check it out. I think you’ll be pleasantly surprised.

The quickest and easiest way to check it out is through the Web Application Gallery.

Slide16Slide17

Check it out and let me know what you think.

ASP.NET and PHP On IIS Together

phpUntitledI got a question the other day about running both ASP.NET and PHP on the same server and whether or not it works. The short answer I gave is “Yes”. The longer answer, I’m going to give here.

In point of fact, both ASP.NET and PHP work really well on the instance of IIS. They can’t share  session state but otherwise it’s a very peaceful existence.

First of all, PHP runs really well on Windows and IIS. There’s a lot of stuff that you probably didn’t know about it. Mark Brown and I did a talk about that at ZendCon – I’ll do a full write up of that talk sometime soon.

There are a ton of great resources out there for running PHP on Windows very well.

Easiest way to install PHP on Windows
Official site for PHP on IIS – Lots of good walk throughs and how to guides here.
RuslanY’s blog about IIS, FastCGI, PHP and other interesting stuff.
Brian Swan’s blog about PHP, SQL Server and more.
PDO driver for Microsoft SQL Server
SQL Server Reporting Services SDK for PHP
PHP: WinCache
Performance improvement in Joomla using WINCACHE user cache – great info on leveraging user cache.
Interop resources from Microsoft and PHP
URL Rewrite module for IIS7

I could keep going but this post is about running both ASP.NET and PHP on the same IIS instance.

Mike Volodarsky wrote a great article on leveraging the integrated pipeline in IIS7 that included leveraging ASP.NET Forms Authentication to restrict access to a PHP application. I’m not going to rehash that entire article but rather recommend that you leverage the applications that are up in the Microsoft Web Application Gallery such as Gallery. These applications are really simple to get set up on IIS7 through the wizard style installer in the WebPI.  

The first scenario that we’ll look at is a PHP application running as a subdirectory on the same server as an ASP.NET application. The first thing I’m going to do is get an ASP.NET application up and running through the Web Platform Installer (WebPI). I’m going to use BlogEngine.NET this demo. If you don’t already have the Web Platform Installer, it’s easy to install by going to http://www.microsoft.com/web/gallery/ and clicking "Install” next to any of the applications that you want to install. If you already have it installed, simply launch the Web Platform Installer, find BlogEngine.NET and start the wizard.

firstIf you want the application to be the root of the web server, then on the page where it’s asking about location, clear out the ‘application name’ field. It makes sense once you see it but it took me a second the first time that I tried it. I already had all of the dependencies installed for BlogEngine.NET so the rest was just following the wizard.

secondOnce BlogEngine.NET is installed, I can browse out to it and make sure that it’s all working. I can, if I want, do some configuration and change the title, skin and the like. However, that’s not the point of this little exercise so I’m going to skip it for the moment.

Now I’ve got an ASP.NET application up and running as the root of my server. Now I need to place the PHP application on the box to show them running side by side. The quick one that I want to install is Gallery which is a well known PHP application that does a good job at photo galleries. There are a number of galleries listed in the Web Application Gallery but the one that we want is “Gallery”.

ThirdAgain, I’m going to install the application through the WebPI. I have most of the dependencies installed already but I’m going to use SQL Server because I’ve already got one application using it, I might as well use it for the other. That’s going to require me to install the Microsoft Driver for PHP for SQL Server 2.0 and it’s associate that helps with IIS specifically. The good news is that these dependencies are selected and installed automatically by the wizard. Once the WebPI installer finishes, click “Launch Website” and finish out the installer.

At this point I’ve got BlogEngine.NET running at http://localhost and Gallery running at http://localhost/gallery proving out scenario one where PHP can run in a sub-directory under ASP.NET. The opposite is true as well but unless someone specifically requests it, I’ll assume that you can switch this example around and do it the other direction where you have a primarily PHP site with a little bit of ASP.NET running on the same server.

These different applications can share HTTP Handlers, URL Rewrite Rules, security rules (as stated in Mike’s article) and a bunch of different aspects of IIS. What they can’t share out of the box is session state. ASP.NET can store session in a number of places, including SQL Server and theoretically it’s possible to write a custom PHP session handler that would read from that same store but I haven’t tried it so I can’t guarantee that it’ll work.

In future posts, I’ll take a look at integrating HttpModules and HttpHandlers into the PHP pipeline and see how that works. In the mean time, have fun mixing and mashing technologies.