Multiple PHP versions on Windows: one site, one FastCGI version
Run PHP 8.3 and 8.4 side by side on IIS with separate directories, FastCGI applications, site-level handlers and per-version php.ini.
- Build
- 26100.33650
- Edition
- Standard / Datacenter
- Architecture
- x64
- Support
- Documentation (E1)
- Evidence
- E1Official documentation
- Verified
- 2026-10-29
- Test machine
- PHP 8.4.27 FastCGI verified on VM 361 Windows 11 26H2; PHP 8.3 side-by-side pattern E1
- Page type
- Method
The short answer
Section titled “The short answer”PHP version is selected by the handler’s scriptProcessor, not by the application pool. To run 8.3 and 8.4 side by side:
- Install each NTS build in its own directory (
C:\PHP\8.3,C:\PHP\8.4). - Each has its own
php.ini. - Register each
php-cgi.exeas a FastCGI application. - Give each site a site-level
*.phphandler pointing at that version. - Keep app pools separate for isolation, but do not expect the pool to choose PHP.
Directory layout
Section titled “Directory layout”C:\PHP\8.3\php-cgi.exeC:\PHP\8.3\php.iniC:\PHP\8.4\php-cgi.exeC:\PHP\8.4\php.iniDo not put both versions in one folder or share ext. A missing/incorrect extension_dir is the usual “extension not found” cause.
Register both FastCGI apps
Section titled “Register both FastCGI apps”Import-Module WebAdministrationAdd-WebConfiguration -PSPath 'MACHINE/WEBROOT/APPHOST' ` -Filter 'system.webServer/fastCgi' ` -Value @{ fullPath = 'C:\PHP\8.3\php-cgi.exe' }Add-WebConfiguration -PSPath 'MACHINE/WEBROOT/APPHOST' ` -Filter 'system.webServer/fastCgi' ` -Value @{ fullPath = 'C:\PHP\8.4\php-cgi.exe' }Both can exist; only the handler decides which one a request uses.
Site-level handler
Section titled “Site-level handler”If the server already has a global PHP_via_FastCGI pointing at 8.4, a PHP 8.3 site can remove it and add its own:
<configuration> <system.webServer> <handlers> <remove name="PHP_via_FastCGI" /> <add name="PHP83_via_FastCGI" path="*.php" verb="*" modules="FastCgiModule" scriptProcessor="C:\PHP\8.3\php-cgi.exe" resourceType="Either" /> </handlers> </system.webServer></configuration>Do not <clear /> all handlers; that removes static content and breaks CSS/images. Remove only the PHP handler you are replacing.
The 8.4 site can keep the global handler or define PHP84_via_FastCGI explicitly. Explicitness is easier to audit.
Per-version php.ini
Section titled “Per-version php.ini”Each version needs its own settings:
; C:\PHP\8.3\php.inicgi.fix_pathinfo=0fastcgi.impersonate=1date.timezone=UTCextension_dir="ext"expose_php=OffIf PHP loads the wrong ini, check php --ini / a phpinfo page. PHPRC can force a directory, but per-version directories + php-cgi next to its ini are simpler.
Verify
Section titled “Verify”& C:\PHP\8.3\php-cgi.exe -v& C:\PHP\8.4\php-cgi.exe -vGet-WebConfiguration -PSPath 'MACHINE/WEBROOT/APPHOST' -Filter 'system.webServer/fastCgi' | Select-Object -ExpandProperty CollectionCreate a site-specific info.php and confirm PHP Version and Loaded Configuration File on each site. Then remove the test page.
Upgrade path
Section titled “Upgrade path”- Add the new version beside the old one.
- Test one site with a site-level handler.
- Compare extensions and
php.ini. - Move sites one at a time.
- Keep the old version until rollback is no longer needed; then remove its FastCGI app and directory.
Lab boundary
Section titled “Lab boundary”PHP 8.4.27 NTS + IIS FastCGI was verified on VM 361. The 8.3 side-by-side setup is E1; use the same procedure on Server 2025 and record both phpinfo pages before calling it E2.