Installing PHP on Windows with IIS

IIS on your dedicated server can interface with the PHP interpreter in one of three ways:

  1. ISAPI: fast, compatible with 32-bit systems or 64-bit systems using 32-bit IIS application pools. This is the IIS equivalent to mod_php and the preferred means of installation.

  2. FastCGI: fast, compatible with 64-bit IIS application pools (does not embed the interpreter inside any IIS process).
  3. CGI: highly compatible, but dog slow. Using CGI is a simple means of isolating configuration problems (is it IIS or PHP?). Do not use this in production NT environments.

This article will focus on points (1) and (2). Your choice of approach will depend on whether or not you are forced into using 64-bit IIS application pools on your server. As noted below, Zend do not distribute a 64-bit build for NT, hence the two approaches for 32 and 64-bit IIS application pools.

ACHTUNG!

The first question you absolutely must ask yourself is whether you really need to run PHP on Windows. As you'll discover, it's a non-trivial process. In contrast, it's almost impossible to fail at running PHP under Linux, and most apps are written with a Linux platform in mind. PHP on Linux is very well supported, and looks like it'll stay that way for the foreseeable eternity. If you still need convincing, you might like to take a look at our notes on PHP on Windows vs Linux article.

PHP4 or PHP5

  • PHP4 is no longer supported and is not recommended. You've had plenty of time to migrate your code to PHP5, it's not even particularly hard.
  • PHP5 is the way to go
  • That said, you can make PHP4 work as well as PHP5, the differences in the procedure are cosmetic.

If you want to use PHP4, modify the paths and directives shown below as appropriate. It's not hard, just read everything.

64-bit mode

PHP is simply not available in a 64-bit compile, they're that retarded. As an aside, their alleged thread-safety is apparently a lie (just like the cake).

Make a note here when a 64-bit PHP build becomes available. This event will deprecate FastCGI installations.

Installing PHP as an IIS ISAPI module

Assumptions

  • A basic working installation of IIS
  • A decent idea of what you're doing

Pre-flight

Preparing IIS for 32-bit ISAPI modules

Skip this section if you are using a 32-bit build of Windows Server 2003.

Ensure IIS is operating in 32-bit compatibility mode (using 32-bit application pools):

cscript %SYSTEMDRIVE%\inetpub\adminscripts\adsutil.vbs GET W3SVC/AppPools/Enable32bitAppOnWin64

Proceed only if you receive the following output:

Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

Enable32bitAppOnWin64           : (BOOLEAN) True

or if you are certain that flipping this value will not break anything. Flip (assert) with:

cscript %SYSTEMDRIVE%\inetpub\adminscripts\adsutil.vbs SET W3SVC/AppPools/Enable32bitAppOnWin64 1

and restart IIS. Test every web application on the system, particularly anything 'Microsofty'.

For more information on the topic, see this Microsoft article.

Caveats

This was originally written with the intention of using the automated MSI installer package. Due to the apparently large quantities of fial, it's now using the ZIP-based manual installation. It's almost as quick, will give you a better insight into how everything comes together, and works.

Credit

Peter Guy wrote the guide off which this is based: http://www.peterguy.com/php/install_IIS6.html

I don't know why it works and the MSI installer doesn't, but I don't really care. If you get the MSI installation to work, good on you.

Download

This is pretty straightforward. You grab the latest PHP zip packages and PECL extensions. Get the thread-safe stuff.

PHP4 doesn't seem to have a set of PECL extensions available. *shrug* You're on your own here, hopefully all the stuff you want/need is included or compiled-in already.

Installation

  • Unzip the archive to C:\PHP5\. It's important that there's no spaces in the path, which breaks things notoriously on windows.

  • Unzip the PECL extensions to the ext directory. (this is "extensions" under PHP4)

Configure

  • Copy php.ini-recommended to php.ini

  • Download a browscap.ini file from http://browsers.garykeith.com/downloads.asp and drop it in the extras/ directory. Make sure you get the PHP-specific one.

  • Fix up a couple of important settings. These aren't all in one place, just find and tweak them.

    extension_dir="C:\PHP5\ext"
    cgi.force_redirect = 0
    session.save_path="C:\WINDOWS\Temp"
    browscap="C:\PHP5\extras\browscap.ini"

%PATH%

It's useful to have PHP in the system path.

  • My Computer -> Properties -> Adavnced -> Environment Variables -> PATH. Prepend C:\PHP5; to the entry. "OK" all the windows to close them.

  • Test this by attempting to run php from a shell. If it works, you should get nothing (PHP is waiting on stdin). ^Z or ^D to gtfo.

Registry modifications

This will tell PHP where to find its php.ini file, at least from the shell (doesn't seem to have any effect on ISAPI operation).

  • Create a file, anywhere, phpfoohack.reg

    Windows Registry Editor Version 5.00
    
    [HKEY_LOCAL_MACHINE\SOFTWARE\PHP]
    "IniFilePath"="C:\\PHP5"
  • Run the file to import the key.
  • Delete the file.

Extensions

Dump this lot at the end of php.ini. You might need to experiment a bit to find a set that doesn't die in a fire. Comment out more as need be, pending your testing. While you may have these DLLs physically present, many of them depend on other stuff being installed, which is why you can't simply enable them all.

This doesn't seem to apply to PHP4, I found it just works anyway.

extension=php_adt.dll
extension=php_amf.dll
extension=php_bcompiler.dll
extension=php_bitset.dll
extension=php_bz2.dll
extension=php_bz2_filter.dll
extension=php_classkit.dll
extension=php_cpdf.dll
extension=php_crack.dll
extension=php_curl.dll
extension=php_cvsclient.dll
extension=php_dio.dll
extension=php_docblock.dll
extension=php_event.dll
extension=php_mbstring.dll ; mbstring must be defined before exif.
extension=php_exif.dll
extension=php_fdf.dll
extension=php_fileinfo.dll
extension=php_filepro.dll
extension=php_gd2.dll ; gif draw - http://www.boutell.com/gd
extension=php_gettext.dll
extension=php_gmp.dll
extension=php_gopher.dll
extension=php_haru.dll
extension=php_htscanner.dll
extension=php_http.dll
extension=php_hyperwave.dll
extension=php_id3.dll
extension=php_imap.dll
extension=php_interbase.dll
extension=php_ldap.dll
extension=php_lzf.dll
extension=php_mailparse.dll ; requires php_mbstring.dll
extension=php_mcrypt.dll ; requires the mcrypt library (libmcrypt.dll - http://mcrypt.sourceforge.net/, http://files.edin.dk/php/win32/mcrypt/, ftp://mcrypt.hellug.gr/pub/crypto/mcrypt/attic/libmcrypt/old/win32/)
extension=php_mcrypt_filter.dll
extension=php_memcache.dll
extension=php_mhash.dll
extension=php_mime_magic.dll
extension=php_ming.dll
extension=php_msql.dll
extension=php_mssql.dll
extension=php_mysql.dll
extension=php_mysqli.dll
extension=php_ntuser.dll
extension=php_oggvorbis.dll
extension=php_openssl.dll
extension=php_operator.dll
extension=php_parsekit.dll
extension=php_phar.dll
extension=php_phpdoc.dll
extension=php_pop3.dll
extension=php_runkit.dll
extension=php_shmop.dll
extension=php_smtp.dll
extension=php_soap.dll
extension=php_sockets.dll
extension=php_spl_types.dll
extension=php_ssh2.dll
extension=php_stats.dll
extension=php_stem.dll
extension=php_timezonedb.dll
extension=php_translit.dll
extension=php_uploadprogress.dll
extension=php_win32ps.dll
extension=php_win32scheduler.dll
extension=php_win32service.dll
extension=php_win32std.dll
extension=php_xmlrpc.dll
extension=php_xsl.dll
extension=php_zip.dll
extension=php_zlib_filter.dll
;extension=php_apc.dll ; Alternative PHP Cache (http://pecl.php.net/package/APC) - significantly increases CPU load
;extension=php_apd.dll
;extension=php_blenc.dll ; if enabled, test page is blank. Transparent PHP Script Encryption using Blowfish (http://pecl.php.net/package/BLENC)
;extension=php_db.dll - deprecated.  Use php_dba.dll instead.
;extension=php_dba.dll
;extension=php_dbase.dll
;extension=php_dbx.dll
;extension=php_domxml.dll ; threw a bunch of "PHP Notice: Constant XML_... already defined ..." errors.
;extension=php_fribidi.dll
;extension=php_ibm_db2.dll ; IBM DB2 database
;extension=php_ifx.dll ; Informix database.
;extension=php_iisfunc.dll ; Enable IIS and service management via PHP (http://kromann.info/article.php?Id=11062861865960000) - significantly increases CPU load
;extension=php_imagick.dll ; ImageMagick (http://pecl.php.net/package/imagick).
;extension=php_ingres.dll ; Ingres database - complains about missing iilibapi.dll
;extension=php_java.dll
;extension=php_maxdb.dll ; requires MySQL maxDB (www.mysql.com/maxdb)
;extension=php_mcve.dll
;extension=php_netools.dll ; requires lcrzo.dll (http://www.icewalkers.com/Linux/Software/516050/lcrzo.html)?  Appears to be a very fragile project. PECL extension page: http://pecl.php.net/package/netools
;extension=php_oci8.dll ; OCI for ORacle databases
;extension=php_oracle.dll ; Oracle database
;extension=php_pdf.dll
;extension=php_pdo.dll
;extension=php_pdo_firebird.dll ; requires php_pdo.dll
;extension=php_pdo_ibm.dll
;extension=php_pdo_informix.dll ; more Informix  ; requires php_pdo.dll
;extension=php_pdo_mssql.dll  ; requires php_pdo.dll
;extension=php_pdo_mysql.dll  ; requires php_pdo.dll
;extension=php_pdo_oci.dll ; more OCI  ; requires php_pdo.dll
;extension=php_pdo_oci8.dll ; yet more OCI  ; requires php_pdo.dll
;extension=php_pdo_odbc.dll  ; requires php_pdo.dll
;extension=php_pdo_pgsql.dll  ; requires php_pdo.dll
;extension=php_pdo_sqlite.dll  ; requires php_pdo.dll
;extension=php_pdo_sqlite_external.dll
;extension=php_pgsql.dll
;extension=php_printer.dll ; significantly increases CPU load
;extension=php_pspell.dll ; ASpell - http://www.aspell.net/win32
;extension=php_radius.dll
;extension=php_rar.dll
;extension=php_sam.dll
;extension=php_sdo.dll
;extension=php_snmp.dll ; Throws a bunch of "Cannot find module" errors.
;extension=php_sqlite.dll ; requires php_pdo.dll
;extension=php_svn.dll ; requires intl3_svn.dll (Subversion Revision control system - http://pecl.php.net/package/svn)
;extension=php_swish.dll
;extension=php_sybase_ct.dll ; sybase database
;extension=php_threads.dll ; significantly increases CPU load
;extension=php_tidy.dll ; significantly increases CPU load

Test extensions

  • Login to the dedicated server on the console by passing the -0 flag to rdesktop (may not be needed, but can't hurt).

  • Create an info.php file somewhere convenient, like C:\Inetpub\wwwroot\

    <?php
    phpinfo();
    ?>
  • Open a shell and cd to the directory containing info.php

  • Run the file. If it runs, great. If not, it'll dump "can't load extension" complaints to the console, and popup windows.

    C:\Inetpub\wwwroot> php info.php

    Based on the error messages, you'll have to guess which extension it is and comment it out in php.ini. Keep doing this until you get no errors and phpinfo is dumped as output.

Sanity-check IIS

You need IIS working properly first. Create an index.html file in C:\Inetpub\wwwroot\ with a simple "hostname OK". Hit up the page and make sure you can see it before proceeding. At this point, IIS will refuse to serve any file extensions it doesn't recognise, giving you a 404 instead, which can be most confusing. While this technically isn't bad (you hopefully won't serve content unexpectedly), it breaks expectations; you expect it to just return the PHP in plain text.

http://nemo.anchor.net.au/index.html

Add the PHP ISAPI Extension to IIS

This allows PHP to be used with IIS.

  1. Fire up the IIS Manager and open the local machine in the left pane.
  2. Select "Web Service Extensions" on the left side, then "Add new web service extension" on the right.
  3. Give it "PHP ISAPI" as the name, and browse for C:\PHP5\php5isapi.dll

  4. Tick the box for "allowed" and close everything up.
  5. If you want, you can add PHP as CGI. Do the same again, giving an appropriate name and using C:\PHP5\php-cgi.exe instead.

PHP4

I'm not sure how you do ISAPI with PHP4, I've not tried. I suspect it's one of the files in C:\PHP4\sapi\. You should use FastCGI anyway, it's as easy as plain CGI, and more reliable. PHP4 has no separate cgi executable, just use php.exe, it seems to work fine.

Enable use of PHP on site/s

Now that PHP is available, you enable on your site/s.

  1. Get properties on "Web Sites" in the left pane (this will apply the config to all sites)
    • Alternatively, get properties on the single site you want PHP on.
  2. "Home Directory" tab, then the "Configuration..." button near the bottom-right
  3. On the "Mappings" tab, the "Add" button.
  4. Browse for the php5isapi.dll or php-cgi.exe, same as before.
  5. .php as the extension.

  6. Limit the verbs it applies to.

    GET,POST,HEAD
  7. OK, close it up.
  8. On the way out, set Execute Permissions to "Scripts Only" on the HomeDir tab.

Restart the default App Pool in IIS Manager. You'll be doing this a lot; this is like gracefully reloading Apache's config.

Making it work in IIS

PHP is dumb and has a hardcoded path to look in the windows directory for php.ini. Yes, there's a perfectly good one in C:\PHP5\. No, it's not using it.

Copy your now-known-to-work C:\PHP5\php.ini to C:\Windows\. Restart the app pool and check out your phpinfo page. http://nemo.anchor.net.au/info.php

You should be able to load up that info file in your browser. Notice the values for the config file path and Loaded Configuration File...

Restart

Hell, y'know what? It probably doesn't work still. I know the mysql extensions absolutely refused to load no matter what I did. Restarting IIS should do it (IISmgr->local computers->all tasks->Restart IIS), but you might as well reboot the machine. This is windows, after all.

It still doesn't work!

Sorry, you're on your own now. Like everyone else, you'll need to stumble around with Windows until it suddenly clicks.

Actually, the dude has a pretty good troubleshooting section on the site, there's no point repeating it here. Big surprise, it's full of inconsistency and workarounds.

http://www.peterguy.com/php/install_IIS6.html#Troubleshoot

Invoking PHP from a FastCGI environment

Procedure

  1. Follow Barney's advice for the ISAPI install, above. There's a bit where he mentions invoking PHP as CGI — get that working and come back to me.

  2. Download Microsoft's FastCGI Extension for Internet Information Services 6.0 and install it. You want the variant for x64 systems (if you're running x64 Windows).

  3. You should now have a fcgiext.ini in either C:\WINDOWS\system32\inetsrv or C:\WINDOWS\SysWOW64\inetsrv. The file should reside in (C:\WINDOWS\system32\inetsrv, so move it there if necessary.) Open it in your editor of choice and append something like the following to the bottom:

    [Types]
    php=Default Web Site
    
    [Default Web Site]
    ExePath=C:\PHP5\php-cgi.exe

    If you've followed Barney's advice to the letter, that path should be correct. Update this accordingly if you're using PHP4. More sophisticated sites may require [http://learn.iis.net/page.aspx/248/configuring-fastcgi-extension-for-iis60/ additional configuration].

  4. Open the Internet Information Services (IIS) Manager.

  5. Descend into Web Service Extensions from the tree on the left.

  6. Ensure the FastCGI Handler is set to Allowed. Right-click on it and select Properties. Click over to the Required Files tab and ensure both of the following files are listed with a status of Allowed:

    1. C:\WINDOWS\system32\inetsrv\fcgiext.dll;

    2. C:\WINDOWS\SysWOW64\inetsrv\fcgiext.dll.

  7. Dismiss any open dialogue boxes to return to the IIS Manager window. Expand and descend into Web Sites from the tree on the left.

  8. Right-click on Default Web Site (or some child within) and click Properties.

  9. Flip over to the Home Directory tab and click the button labeled, Configuration.

  10. Locate the .php extension and set its executable path to C:\WINDOWS\system32\inetsrv\fcgiext.dll. The check boxes labeled, Script engine and Verify that file exists should both be checked.

  11. Dismiss any open dialogue boxes to return to the IIS Manager window. Restart IIS and test your configuration. There will be an initial delay as the FastCGI parent loads the PHP interpreter into memory, but successive requests should be satisfied with minimal latency.

Keep in mind

  • It is probably not necessary to copy php.ini to C:\Windows as it is when you are using the ISAPI module. If you find that this is true, you should get rid of C:\Windows\php.ini to reduce confusion.