PHP runs on IIS through FastCGI: IIS hands .php requests to a pool of php-cgi.exe processes. It works well for PHP apps that must live on Windows (alongside .NET apps, or with Windows-only dependencies). For most pure PHP workloads (WordPress, Laravel), Linux with Nginx and PHP-FPM is simpler and faster. If you need Windows, here’s how to set it up properly.
1. Install the CGI role service
Install-WindowsFeature Web-CGI
(Requires IIS. See install IIS.)
2. Install PHP
- Download the Non Thread Safe (NTS) x64 build of PHP for Windows from the official PHP for Windows site (
windows.php.net). NTS is the right build for FastCGI. - Extract it to a folder without spaces, for example
C:\PHP\8.3. - Install the matching Visual C++ Redistributable (the download page says which version is needed).
- Copy
php.ini-productiontophp.ini.
3. Configure php.ini
extension_dir = "C:\PHP\8.3\ext"
cgi.fix_pathinfo = 1
fastcgi.impersonate = 1
date.timezone = UTC
memory_limit = 256M
upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 120
error_log = "C:\PHP\logs\php_errors.log"
extension=curl
extension=fileinfo
extension=gd
extension=intl
extension=mbstring
extension=mysqli
extension=openssl
extension=pdo_mysql
extension=zip
zend_extension=opcache
opcache.enable=1
opcache.memory_consumption=128
See php.ini settings.
4. Map .php to PHP in IIS
IIS Manager → server (or site) → Handler Mappings → Add Module Mapping:
- Request path:
*.php - Module:
FastCgiModule - Executable:
C:\PHP\8.3\php-cgi.exe - Name:
PHP 8.3
Accept the prompt to create a FastCGI application. Or use PowerShell/appcmd:
& $env:windir\system32\inetsrv\appcmd.exe set config /section:system.webServer/fastCgi /+"[fullPath='C:\PHP\8.3\php-cgi.exe']"
& $env:windir\system32\inetsrv\appcmd.exe set config /section:system.webServer/handlers /+"[name='PHP 8.3',path='*.php',verb='*',modules='FastCgiModule',scriptProcessor='C:\PHP\8.3\php-cgi.exe',resourceType='Either']"
Add index.php to the site’s Default Document list.
5. Tune FastCGI
IIS Manager → server → FastCGI Settings → your PHP entry:
- Instance MaxRequests: about 10000 (recycle processes periodically). Set the environment variable
PHP_FCGI_MAX_REQUESTSto the same value. - Max Instances: 0 (auto), or a fixed number based on CPU and RAM.
- Activity Timeout / Request Timeout: raise for long-running scripts (and keep
max_execution_timein line).
6. Test
Create C:\inetpub\wwwroot\info.php containing <?php phpinfo();, open it in a browser, check the version and extensions, then delete the file. It exposes configuration details.
Permissions
The app pool identity (IIS AppPool\<pool name>) needs read access to the site folder, and modify access only to folders the app writes to (uploads, cache):
icacls "C:\Sites\example\wp-content\uploads" /grant "IIS AppPool\example:(OI)(CI)M"
WordPress on IIS
- URL Rewrite is required for pretty permalinks. WordPress writes
web.configrules when permalinks are saved (if it can write the file), or add the standard WordPress rewrite rule manually. See IIS URL Rewrite. - Use MySQL or MariaDB for Windows (or a separate Linux database server).
- Expect lower performance than Nginx + PHP-FPM on Linux. If you’re free to choose, a Linux VPS is the better WordPress host. See WordPress VPS hosting.
Multiple PHP versions
Install each version in its own folder (C:\PHP\8.2, C:\PHP\8.3), register each as a FastCGI application, and set the handler mapping per site, so different sites use different versions.
Troubleshooting
- 500 error with no details: check
C:\PHP\logs\php_errors.log, and temporarily enable detailed errors in IIS for local requests. - “The FastCGI process exited unexpectedly”: usually a missing Visual C++ runtime, or an extension that doesn’t match the PHP version.
- Slow first request: OPcache is off, or the FastCGI pool recycles too often.
Updating PHP
Download the new NTS build, extract it to a new folder, copy your php.ini, update the FastCGI and handler paths, and test. Keeping versioned folders makes rollback easy.
Quick reference
| Step | Action |
|---|---|
| Role | Install-WindowsFeature Web-CGI |
| PHP build | Non Thread Safe x64 |
| Handler | *.php → FastCgiModule → php-cgi.exe |
| Performance | OPcache on, MaxRequests ~10000 |
| Pretty URLs | URL Rewrite module |
Related: host ASP.NET on IIS and Windows VPS.