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 $trueRestart if prompted:
Restart-Computer -ForceDownload 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 NameConfigure 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.iniEssential 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 settingsEnable 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=opcacheCreate 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 -vClose and reopen PowerShell for PATH change to take effect.
Configure IIS FastCGI
Add FastCGI Handler
Open IIS Manager (inetmgr.exe):
- Select server name in left panel
- Double-click Handler Mappings
- Click Add Module Mapping (right panel)
Configure:
Request Path: *.php
Module: FastCgiModule
Executable: C:\PHP\php-cgi.exe
Name: PHP_via_FastCGIClick OK.
Configure FastCGI Settings
In IIS Manager:
- Select server name
- Double-click FastCGI Settings
- Select PHP-CGI entry
- Right-click Edit
Configure:
Activity Timeout: 300
Instance Max Requests: 10000
Rapid-Fail Protection: Check
Rapid-Fail Protection: Max Processes: 10Click OK.
Set Default Document
Add index.php to default documents:
- Select server or site in IIS Manager
- Double-click Default Document
- Click Add (right panel)
- Enter:
index.php - Click OK
Order preference:
index.php
index.html
index.htmTest PHP Installation
Create Test File
Create C:\inetpub\wwwroot\test.php:
@"
<?php
phpinfo();
?>
"@ | Out-File -Encoding UTF8 C:\inetpub\wwwroot\test.phpTest in Browser
Open browser and navigate to:
http://localhost/test.phpYou should see PHP information. If working, delete test file:
Remove-Item C:\inetpub\wwwroot\test.phpInstall URL Rewrite Module
For WordPress and other CMS:
- Download URL Rewrite Module
- Run installer
- Restart IIS:
iisreset /restartApplication Pool Configuration
Set Application Pool Identity
- In IIS Manager, select Application Pools
- Right-click DefaultAppPool → Advanced Settings
- 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 /restartVerify extensions loaded:
php -mMonitor and Troubleshoot
Check PHP Configuration
# Show all configuration
php -i
# Check for errors
php -l C:\inetpub\wwwroot\index.phpView 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 -20PHP 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 -WaitPerformance 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 = 1Restart IIS:
iisreset /restartSecurity Best Practices
Hide PHP Version
In php.ini:
expose_php = OffDisable Dangerous Functions
In php.ini:
disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_sourceEnable HTTPS Only
In IIS Manager:
- Select site
- Right-click Edit Bindings
- Add HTTPS binding with SSL certificate
- 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 50PHP 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 missingHigh Memory Usage
# Reduce PHP processes
# In IIS Manager → FastCGI Settings → Max Processes: 4
# Or increase server RAMAlways 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:
- Create database in MySQL
- Extract WordPress to
C:\inetpub\wwwroot - Run WordPress installer at
http://your-domain/wp-admin/install.php - Configure
wp-config.phpwith database credentials
Required extensions for WordPress:
mysqliorpdo_mysqlcurlgdmbstringopenssl
All enabled by default in this configuration.
Task Scheduler: Automation on Windows Server
Create and manage automated tasks on Windows Server with Task Scheduler. Windows equivalent of Linux cron for backups, scripts and maintenance.
PowerShell for Server Management
Essential PowerShell commands and scripts for managing Windows Server, processes, services, disks, networking, and automation