Custom PHP version on IIS Express and WebMatrix 3

PHP 7 with OPcache in IIS Express for Microsoft WebMatrix 3, learn how to create your own PHP development environment easily with Microsoft WebMatrix and IIS Express and your own custom PHP version.
Published on Tuesday, 19 August 2014

This guide also applies to newer PHP versions, just change the version numbers.

PHP in IIS Express and Microsoft WebMatrix 3

At the time of first writing, the default PHP version for Microsoft IIS Express and WebMatrix 3 was PHP 5.5.11. Which was good because it's 5.5.x. Sometimes you may need to upgrade PHP to 5.6 or 7.0 in IIS Express, or even downgrade the PHP version (don't do this). If you have to match your development environment to your web hosting production environment for example. Or if you want to use OPcache and/or WinCache.

The PHP modules OPcache and WinCache are PHP accelerators, used to cache PHP byte-code (the compiled version of the PHP script). PHP accelerators increase website performance and decrease CPU usage, making it win-win extensions for your development and production environments.

Even using the command line, with AppCmd, it's still pretty easy to install a custom PHP version in IIS Express and WebMatrix 3.

About IIS Express

IIS Express is a lightweight, self-contained version of IIS optimized for developers. IIS Express makes it easy to use the most current version of IIS to develop and test websites. It has all the core capabilities of IIS 7 and above as well as additional features designed to ease website development.

About Microsoft WebMatrix 3

Microsoft WebMatrix is a free, lightweight, cloud-connected web development tool. Create, publish, and maintain your website with ease

Install PHP 5.6 or PHP 7 in WebMatrix 3

If PHP 5.6 is not yet installed, and you want to install PHP 5.6 with WebMatrix 3, start the program and create a new empty site. Under Site, click Settings and check Enable PHP under PHP Settings.

WebMatrix3 Settings Add PHP

The Install Product screen opens, in which you have to click Next.

WebMatrix3 Install PHP 5.5 Step 1

In the second screen you see that the Microsoft Visual C++ 2012 Redistributable Package is required. The 'why' in this is that Microsoft continues to optimize PHP for Windows Server/IIS. Here is a nice article about how Microsoft optimizes PHP for Windows/IIS.

So, just click I Accept.

WebMatrix3 Install PHP 5.5 Step 2

PHP is downloaded, configured and installed on your system in IIS Express and WebMatrix 3. Click OK after it finished.

WebMatrix3 Install PHP 5.5 Step 3

On the Windows command-line interface cmd.exe (Windows key + R), you can verify PHP is installed in IIS Express using AppCmd.exe. The AppCmd.exe executable is located in C:\Program Files (x86)\IIS Express:

AppCmd list config /section:system.webServer/fastCgi

It'll output:

<system.webServer>
  <fastcgi>
    <application fullPath="C:\Program Files (x86)\iis express\PHP\v5.5\php-cgi.exe"
      monitorChangesTo="php.ini"
      activityTimeout="600"
      requestTimeout="600"
      instanceMaxRequests="10000">
      <environmentvariables>
        <environmentvariable
          name="PHP_FCGI_MAX_REQUESTS"
          value="10000">
        </environmentvariable>
        <environmentvariable
          name="PHPRC"
          value="C:\Program Files (x86)\iis express\PHP\v5.5">
        </environmentvariable>
      </environmentvariables>
    </application>
  </fastcgi>
</system.webServer>

And the *.php handler

AppCmd list config /section:system.webServer/handlers | findstr /i php
<add
  name="PHP55_via_FastCGI"
  path="*.php"
  verb="GET,HEAD,POST"
  modules="FastCgiModule"
  scriptProcessor="C:\Program Files (x86)\iis express\PHP\v5.5\php-cgi.exe"
  resourceType="Either"
>

The resourceType="Either" tells IIS to execute PHP for requests to both files and directories. I don't want PHP to execute on directory requests, therefore I set this to resourceType="File" later on.

Protip: Never use resourceType="Unspecified"!

Display current PHP configuration with phpinfo()

Next, create a new file in our WebMatrix 'EmptySite', in which you can display PHP's configuration settings. This is done using PHP's phpinfo() function. Just name that file phpinfo.php.

WebMatrix3  Create New PHP File

WebMatrix3 PHP phpinfo() function

Save the file and click Run to see its output. If you receive a HTTP Error 403.14 - Forbidden after clicking run, just add /phpinfo.php to the URI after the port number: http://localhost:28429/phpinfo.php (in my case).

This page gives us some information, like PHP's version number:

WebMatrix3 display current PHP version

and the location of the php.ini file:

WebMatrix3 display current php.ini location

Just scroll down the page to learn about PHP's configuration. That could be important. According to PHP.net, the current version of PHP is 5.5.14 and I want to use that, with OPcache. And that's why this tutorial exists. Using the AppCmd command, I can configure IIS Express and PHP the way I want and you can too.

How to install and set up PHP 7 and fastCgi configuration in IIS Express

Please note this information is a bit dated...

Download PHP 7.0.7 VC14 x86 Non Thread Safe (the Zip variant and that Non Thread Safe part is important!) from http://windows.php.net/download/. For the ease of this tutorial, I chose to install PHP in c:\php7. You, of course, may use whatever location you want.

Unzip the archive in your Downloads location. Two sample php.ini files are available: php.ini-development and php.ini-production.

I'm used to using the production sample php.ini, but if you are using this guide to set up a development environment, you may very well be using the development sample. That one's more verbose with error messages and notices. Just copy php.ini-development or php.ini-production to php.ini.

Open php.ini in your favorite text editor (Notepad++ is mine). I won't go through all configuration settings and extensions, some of the most important changes to make are:

; cgi.force_redirect = 1
cgi.force_redirect = 0
;fastcgi.impersonate = 1
fastcgi.impersonate = 1
; fastcgi.logging = 0
fastcgi.logging = 0
; date.timezone =
date.timezone = "Europe/Amsterdam"

Enable OPcache:

; opcache.enable=0
opcache.enable=1 

Open a new tab in Notepad++ and put the contents of http://curl.haxx.se/ca/cacert.pem in there. Save the file as cacert.pem in your PHP's extra folder and put the absolute path to that file as curl.cainfo:

; curl.cainfo =
curl.cainfo = "c:\php7\extras\cacert.pem"

This is important to prevent CURLOPT_SSL_VERIFYPEER errors with cURL.

Load OPcache Zend Extension in php.ini, at the end of the file

; use a full, absolute path!
zend_extension = c:\php7\ext\php_opcache.dll

Once you're satisfied with your php.ini file, save the file and copy your entire PHP directory to the desired location. Rename the directory if necessary.

Configure PHP in IIS Express

We may choose to delete the current PHP configuration in IIS Express using AppCmd, but I'm not. I'm adding this PHP version to the IIS Express configuration. Why? Maybe we want to add additional PHP configurations, for example with WinCache, and now you'll learn how to add, and not remove a configuration setting. No thanks :P

The only downside to this is: we need to redo these steps for every new site we add in WebMatrix 3, and we have to set up the handler we want to use in that website's web.config configuration file. I haven't taken the time yet to find out how to use your own PHP version with WebMatrix 3 permanently.

To add a PHP configuration, I use a series of AppCmd commands. It configures almost everything. Don't be scared.

Configure fastCgi/PHP with appcmd

These are the commands to set up a new fastCgi configuration in IIS and a PHP handler called New_PHP. Each AppCmd command on one line:

Appcmd.exe set config `
  /section:system.webServer/fastCgi `
  /+"[fullPath='c:\php7\php-cgi.exe', `
    arguments='', `
    maxInstances='0', `
    idleTimeout='300', `
    activityTimeout='89', `
    requestTimeout='90', `
    instanceMaxRequests='9999', `
    protocol='NamedPipe', `
    flushNamedPipe='False']" `
  /commit:apphost

AppCmd.exe set config `
  /section:system.webServer/fastCgi `
  /+"[fullPath='c:\php7\php-cgi.exe', `
    arguments=''].environmentVariables.[name='PHP_FCGI_MAX_REQUESTS', value='10000']" `
  /commit:apphost
  
  AppCmd.exe set config `
  /section:system.webServer/fastCgi `
  /+"[fullPath='c:\php7\php-cgi.exe', `
    arguments=''].environmentVariables.[name='PHPRC', value='c:\php7\php.ini']" `
  /commit:apphost
  
  AppCmd.exe set config `
  /section:system.webServer/handlers `
  /+"[name='New_PHP', `
    path='*.php', `
    verb='*', `
    modules='FastCgiModule', `
    scriptProcessor='c:\php7\php-cgi.exe', `
    resourceType='File', `
    allowPathInfo='true', `
    requireAccess='Script', `
    responseBufferLimit='256']" `
  /commit:apphost

Here you see the resourceType="File" that I mentioned earlier. PHP is only executed for requests on files. I'm not much for defaults and like to configure as much as possible... This added a new fastCgi and PHP handler in our applicationHost.config file, as shown by AppCmd:

AppCmd.exe list config `
  /section:system.webServer/handlers | findstr php
<add
  name="New_PHP"
  path="*.php"
  verb="*"
  modules="FastCgiModule"
  scriptProcessor="c:\php7\php-cgi.exe"
  resourceType="File"
  requireAccess="Script"
  allowPathInfo="true"
  responseBufferLimit="256"
/>

<add
  name="PHP55_via_FastCGI"
  path="*.php"
  verb="GET,HEAD,POST"
  modules="FastCgiModule"
  scriptProcessor="C:\Program Files (x86)\iis express\PHP\v7.0\php-cgi.exe"
  resourceType="Either"
/>
AppCmd.exe list config /section:system.webServer/fastCgi
<system.webServer>
  <fastcgi>
    <application
      fullPath="C:\Program Files (x86)\iis express\PHP\v7.0\php-cgi.exe"
      monitorChangesTo="php.ini"
      activityTimeout="600"
      requestTimeout="600"
      instanceMaxRequests="10000">
      <environmentvariables>
        <environmentvariable
          name="PHP_FCGI_MAX_REQUESTS"
          value="10000">
        </environmentvariable>
        <environmentvariable
          name="PHPRC"
          value="C:\Program Files (x86)\iis express\PHP\v7.0">
        </environmentvariable>
      </environmentvariables>
    </application>
    <application
      fullPath="c:\php7\php-cgi.exe"
      arguments=""
      maxInstances="0"
      idleTimeout="300"
      activityTimeout="89"
      requestTimeout="90"
      instanceMaxRequests="9999"
      protocol="NamedPipe"
      flushNamedPipe="false">
      <environmentvariables>      
        <environmentvariable
          name="PHP_FCGI_MAX_REQUESTS"
          value="10000">
        </environmentvariable>
        <environmentvariable
          name="PHPRC"
          value="c:\php7\php.ini">
        </environmentvariable>
      </environmentvariables>
    </application>
  </fastcgi>
</system.webServer>

Now we have to let our website make use of this versions, so delete the other handler from this website's configuration. Open up the web.config configuration file for your EmptySite, which is located in, or somewhere near, C:\Users\UserName\Documents\My Web Sites\EmptySite\ and edit it to have the following contents:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <handlers>
      <!-- remove handlers -->
      <remove name="PHP via FastCGI" />
      <remove name="New_PHP" />
      <!-- add handler -->
      <add name="New_PHP" path="*.php" verb="*"
        modules="FastCgiModule"
        scriptProcessor="c:\php7\php-cgi.exe"
        resourceType="File"
        requireAccess="Script"
        allowPathInfo="true"
        responseBufferLimit="256" />
    </handlers>
  </system.webServer>
</configuration>

Refresh your phpinfo.php and you'll see PHP Version 5.5.15 and Zend OPcache v7.0.4-dev installed.

Protip: Remove fastCgi/PHP configuration and handler

If you want to remove a certain fastCgi/PHP configuration and its handler, use the following AppCmd commands:

Remove system.webServer/fastCgi Remove a fastCgi configuration setting with AppCmd.exe:

Appcmd.exe set config `
  /section:system.webServer/fastCgi `
  /-"[fullPath='C:\Program Files (x86)\iis express\PHP\v5.5\php-cgi.exe']" `
  /commit:apphost

Remove system.webServer/handlers Remove a PHP handler with AppCmd.exe:

AppCmd.exe set config `
  /section:system.webServer/handlers `
  /-"[name='PHP55_via_FastCGI']"

Conclusion configuring your own PHP version in IIS Express and Microsoft WebMatrix 3

This guide showed you how easy it is to set up an alternative PHP version in Microsoft WebMatrix 3. If you have anything to add, or ran into problems, please respond by leaving a comment.

Update: I updated the PHP version numbers in this article to PHP 5.6 and PHP 7 for IIS Express. Drop me a comment if I've missed a spot.