Windows Server

IIS + PHP on Windows Server

Install and configure PHP on IIS for Windows Server, FastCGI setup, php.ini optimization and common extensions

This guide covers installing and configuring PHP on Internet Information Services (IIS) for Windows Server with FastCGI support.


Requirements

  • Windows Server 2016 or later
  • Administrator access
  • PowerShell 5.0+
  • 2GB+ RAM
  • 5GB+ disk space

Install IIS with CGI

Enable IIS Features

Open PowerShell as Administrator:

# Install IIS and CGI role
Install-WindowsFeature -Name Web-Server, Web-CGI -IncludeManagementTools

# Verify installation
Get-WindowsFeature Web-* | Where-Object Installed -EQ $true

Restart if prompted:

Restart-Computer -Force

Download and Install PHP

Download PHP

Visit windows.php.net/download and download:

  • Version: PHP 8.2 or 8.3 (current stable)
  • Type: Non Thread Safe (NTS) x64
  • Format: .zip

Extract to C:\PHP:

# Create directory
New-Item -ItemType Directory -Path C:\PHP -Force

# Extract zip (adjust version number)
Expand-Archive -Path "C:\Downloads\php-8.3.0-nts-Win32-x64-vs17.zip" -DestinationPath "C:\PHP"

# Verify
Get-ChildItem C:\PHP | Select-Object Name

Configure php.ini

Copy and Edit Configuration

# Copy default config
Copy-Item C:\PHP\php.ini-production C:\PHP\php.ini

# Open in Notepad
notepad C:\PHP\php.ini

Essential Settings

Edit php.ini:

[PHP]
; Timezone
date.timezone = Europe/London

; Maximum upload size
upload_max_filesize = 256M
post_max_size = 256M

; Maximum execution time (seconds)
max_execution_time = 300

; Display errors (disable in production)
display_errors = Off
log_errors = On
error_log = C:\PHP\logs\error.log

; Extension directory
extension_dir = "ext"

; Performance
opcache.enable = 1
opcache.memory_consumption = 128
opcache.max_accelerated_files = 10000
opcache.revalidate_freq = 60

[CLI]
; CLI specific settings

Enable Extensions

Uncomment essential extensions in php.ini:

; Database
extension=pdo_mysql
extension=mysqli

; Compression
extension=curl
extension=gd

; Text processing
extension=mbstring
extension=openssl

; Performance
extension=opcache

Create Error Log Directory

New-Item -ItemType Directory -Path C:\PHP\logs -Force
icacls C:\PHP\logs /grant "IIS AppPool\DefaultAppPool:(OI)(CI)M"

Add PHP to System PATH

# Get current PATH
$env:Path

# Add C:\PHP to PATH permanently
[Environment]::SetEnvironmentVariable(
    'Path',
    $env:Path + ';C:\PHP',
    'Machine'
)

# Verify
php -v

Close and reopen PowerShell for PATH change to take effect.


Configure IIS FastCGI

Add FastCGI Handler

Open IIS Manager (inetmgr.exe):

  1. Select server name in left panel
  2. Double-click Handler Mappings
  3. Click Add Module Mapping (right panel)

Configure:

Request Path: *.php
Module: FastCgiModule
Executable: C:\PHP\php-cgi.exe
Name: PHP_via_FastCGI

Click OK.

Configure FastCGI Settings

In IIS Manager:

  1. Select server name
  2. Double-click FastCGI Settings
  3. Select PHP-CGI entry
  4. Right-click Edit

Configure:

Activity Timeout: 300
Instance Max Requests: 10000
Rapid-Fail Protection: Check
Rapid-Fail Protection: Max Processes: 10

Click OK.


Set Default Document

Add index.php to default documents:

  1. Select server or site in IIS Manager
  2. Double-click Default Document
  3. Click Add (right panel)
  4. Enter: index.php
  5. Click OK

Order preference:

index.php
index.html
index.htm

Test PHP Installation

Create Test File

Create C:\inetpub\wwwroot\test.php:

@"
<?php
phpinfo();
?>
"@ | Out-File -Encoding UTF8 C:\inetpub\wwwroot\test.php

Test in Browser

Open browser and navigate to:

http://localhost/test.php

You should see PHP information. If working, delete test file:

Remove-Item C:\inetpub\wwwroot\test.php

Install URL Rewrite Module

For WordPress and other CMS:

  1. Download URL Rewrite Module
  2. Run installer
  3. Restart IIS:
iisreset /restart

Application Pool Configuration

Set Application Pool Identity

  1. In IIS Manager, select Application Pools
  2. Right-click DefaultAppPoolAdvanced Settings
  3. Set Identity to appropriate user

Typical configurations:

  • ApplicationPoolIdentity: Built-in, limited permissions
  • NetworkService: More permissions, recommended for production

File Permissions

Set proper permissions on web directories:

# Grant IIS AppPool read/execute permissions
icacls "C:\inetpub\wwwroot" /grant "IIS AppPool\DefaultAppPool:(OI)(CI)R"

# Grant write permissions only where needed (uploads, temp)
icacls "C:\inetpub\wwwroot\uploads" /grant "IIS AppPool\DefaultAppPool:(OI)(CI)M"

Enable Additional Extensions

Install Common Extensions

For WordPress, Drupal, etc., enable:

# Uncomment in php.ini:
# extension=curl
# extension=gd
# extension=mbstring
# extension=pdo_mysql
# extension=openssl

# Restart PHP/IIS
iisreset /restart

Verify extensions loaded:

php -m

Monitor and Troubleshoot

Check PHP Configuration

# Show all configuration
php -i

# Check for errors
php -l C:\inetpub\wwwroot\index.php

View IIS Logs

# IIS logs location
Get-Item C:\inetpub\logs\LogFiles\W3SVC1 | Select-Object FullName

# Recent errors
Get-Content C:\inetpub\logs\LogFiles\W3SVC1\u_ex*.log | Tail -20

PHP Error Log

# View PHP error log
Get-Content C:\PHP\logs\error.log -Tail 20

# Monitor in real-time
Get-Content C:\PHP\logs\error.log -Tail 1 -Wait

Performance Optimization

Enable OPcache

In php.ini:

[opcache]
opcache.enable = 1
opcache.memory_consumption = 256
opcache.max_accelerated_files = 10000
opcache.interned_strings_buffer = 16
opcache.revalidate_freq = 60
opcache.use_cwd = 0
opcache.validate_timestamps = 1

Restart IIS:

iisreset /restart

Security Best Practices

Hide PHP Version

In php.ini:

expose_php = Off

Disable Dangerous Functions

In php.ini:

disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source

Enable HTTPS Only

In IIS Manager:

  1. Select site
  2. Right-click Edit Bindings
  3. Add HTTPS binding with SSL certificate
  4. Redirect HTTP to HTTPS via rewrite rule

Troubleshooting

502 Bad Gateway / 500 Error

# Check FastCGI process
Get-Process | Where-Object {$_.Name -like "*php*"}

# Restart IIS
iisreset /restart

# Check PHP syntax
php -l "C:\inetpub\wwwroot\index.php"

# Check error log
Get-Content C:\PHP\logs\error.log -Tail 50

PHP Not Executing (Shows Source Code)

# Verify handler mapping
Get-IISConfigSection -SectionPath "system.webServer/handlers" | Get-IISConfigElement | Where {$_.Attributes["name"].Value -eq "PHP_via_FastCGI"}

# Re-add handler mapping in IIS Manager if missing

High Memory Usage

# Reduce PHP processes
# In IIS Manager → FastCGI Settings → Max Processes: 4

# Or increase server RAM

Always use PHP Non Thread Safe (NTS) with FastCGI on IIS, never the Thread Safe (TS) version. Using TS will cause crashes and instability.


WordPress Configuration

After setting up PHP, WordPress installation is straightforward:

  1. Create database in MySQL
  2. Extract WordPress to C:\inetpub\wwwroot
  3. Run WordPress installer at http://your-domain/wp-admin/install.php
  4. Configure wp-config.php with database credentials

Required extensions for WordPress:

  • mysqli or pdo_mysql
  • curl
  • gd
  • mbstring
  • openssl

All enabled by default in this configuration.

On this page