Current situation: PHP2Shell. Two critical PHP vulnerabilities (CVSS 9.2) allow malicious code without login. Patches since 21 October 2026.What to do now →

Updating PHP on Windows

Windows has no automatic PHP update. If you choose the right variant, verify the download and restart all processes, you bring the PHP2Shell patch cleanly onto every machine.

Last updated 6 min readHosting and distributions

In short: On Windows you update PHP by hand: download the fixed version from php.net, choose the same variant (Thread Safe or Non Thread Safe) and architecture, verify the download by SHA-256, carry over php.ini and extensions, switch the path and restart all PHP processes. The update is especially urgent if Apache on Windows loads PHP as a module, because the PHP team rates this operating mode highest for PHP2Shell.

Where PHP hides on Windows machines

Windows servers with PHP are more common than many think. Rarely is it the big website; often it is intranets, specialist applications or tools that someone set up years ago. Operation under IIS is described in detail on the page Securing PHP on Windows and IIS. This article covers the update itself and the cases beyond IIS.

Typical places to find PHP are Apache for Windows with PHP as a module, developer packages such as XAMPP, WampServer or Laragon that ended up on a server, separate PHP copies inside specialist applications and PHP scripts in scheduled tasks. The following PowerShell commands only read and help with finding them:

# Find all php.exe on drive C: (takes a while on large drives)
Get-ChildItem -Path C:\ -Filter php.exe -Recurse -ErrorAction SilentlyContinue |
  Select-Object FullName, LastWriteTime

# Which php.exe is in the search path?
where.exe php

# Running PHP and Apache processes with path and start time
Get-Process php*, httpd -ErrorAction SilentlyContinue | Select-Object Name, Id, StartTime, Path

# Version and loaded configuration of an installation (path as an example)
& "C:\PHP\8.4\php.exe" -v
& "C:\PHP\8.4\php.exe" --ini

Important: if PHP runs as an Apache module, there is no separate PHP process. PHP is then inside the httpd.exe process. Anyone who searches only for php-cgi processes overlooks these installations.

Scheduled tasks that call PHP scripts, for example for imports, reports or data reconciliation, are also easily forgotten. They often use their own, older php.exe. For PHP2Shell they count as less exposed, because according to php.net's statements so far the command line is not among the affected operating modes; when replacing PHP they must still point to the new path, otherwise the old installation stays in use and is never removed.

# Scheduled tasks that call PHP
Get-ScheduledTask | Where-Object { $_.Actions.Execute -match 'php' } |
  Select-Object TaskName, TaskPath, @{n='Programm';e={$_.Actions.Execute}}

Developer machines are a topic of their own. XAMPP and similar packages start Apache with PHP as a module and are often reachable across the entire company network. There too, the PHP needs updating, and the web server should listen only on the machine itself.

Thread Safe or Non Thread Safe: the right variant

php.net offers every Windows version in several variants. For the replacement, the same variant and architecture as before apply, otherwise the web server or extensions will not load.

Feature Options When to use which
Thread safety NTS (Non Thread Safe), TS (Thread Safe) according to php.net, NTS for FastCGI, such as IIS, and the command line; TS for PHP as a module in Apache
Architecture x64, x86 php.net recommends x64
Compiler VS16, VS17 requires the Visual C++ Redistributable for Visual Studio 2015 to 2022

For PHP 8.5, php.net listed version 8.5.12 of 21 October 2026 when checked on 25 October 2026, as a ZIP archive in all four combinations. You select the other supported branches on the same page. The fixed versions are 8.5.12, 8.4.27, 8.3.36 and 8.2.35. For 8.1 and older there are no official updates any more.

PHP update on Windows: verify the download and replace cleanly

  1. Download the fixed version: from the Windows download page on php.net, matching variant and architecture.
  2. Compare the checksum: php.net gives a SHA-256 value for each archive. If it differs, do not use the file.
  3. Unpack into a new folder: for example C:\PHP\8.4.27, so that the old version is kept as a way back.
  4. Carry over the configuration: copy the existing php.ini and compare it with the new php.ini-production.
  5. Check extensions: additional DLL files from third parties must match version, variant and architecture.
  6. Switch the path: in the FastCGI entry, in Apache's LoadModule line or in the PATH environment variable.
  7. Restart and verify: restart the web server service and scheduled tasks, then check version and start times.
# Compute the SHA-256 of the downloaded file and compare it with php.net
Get-FileHash .\php-8.5.12-nts-Win32-vs17-x64.zip -Algorithm SHA256

# After the switch: loaded extensions and version of the new installation
& "C:\PHP\8.5.12\php.exe" -m
& "C:\PHP\8.5.12\php.exe" -v

If PHP does not start after the switch or reports a missing DLL, the Visual C++ Redistributable in the matching architecture is often missing, or an extension does not fit the new version. The error shows up fastest if you call php.exe -v directly on the command line before you switch the web server. What the individual entries in php.ini do is explained in php.ini explained.

Apache on Windows: take module mode seriously

Many older Windows installations integrate PHP directly into Apache via a LoadModule line. Technically that is the same as mod_php on Linux. The PHP team rates the PHP2Shell risk highest exactly there, because an exploit was demonstrated before any application code even runs. Background is at Why mod_php is especially at risk.

Which modules an Apache loads is shown by httpd.exe -M in the installation's bin folder; the command only reads. If a PHP module appears there, the update takes priority. In the medium term, switching to PHP via FastCGI with an NTS build is worthwhile, so that PHP runs in its own processes. That requires a test, because configuration and permissions change.

Important

Replacing the files does not close the vulnerability yet. As long as the Apache service, IIS application pools or scheduled tasks run with the old version, the vulnerability stays open. Check the start time of every process after the update.

After the update: verification and traces

For each installation, record path, version, variant and date of the switch. Remove old PHP folders only once the new version runs stably, and then really remove them, so they are not accidentally integrated again.

An update does not remove malware. If a Windows server was reachable from the internet in the days before the patch, check web directories for new script files, scheduled tasks and local accounts for anything unknown, and secure the web server logs from 20 October onward. How to recognize a break-in is described in Am I already compromised?.

How does PHP SOS help?

  • Find all installations: We search for PHP on your Windows systems, including in Apache modules, developer packages and specialist applications.
  • Replace and prove: Through the PHP patch service, we switch to the fixed version, verify checksums and document version and process start.
  • Improve the operating mode: Where PHP runs as an Apache module, we plan and test the move to FastCGI.
  • Check for traces: We secure logs and examine the systems for signs of an attack.

Frequently asked questions

Does Windows Update also update PHP?

No. PHP is not part of Windows. It comes as a ZIP archive from php.net, as part of a package such as XAMPP, or with a specialist application, and must be updated by that same route.

Do I need the Thread Safe or the Non Thread Safe version?

According to php.net, NTS is intended for FastCGI, such as IIS, and for the command line. TS is intended for operation as a module in the web server, such as Apache. When updating, take the same variant as before.

How do I check that the PHP download is genuine?

php.net gives a SHA-256 checksum for every Windows archive. With Get-FileHash in PowerShell, you compute the checksum of the downloaded file and compare both values character by character.

I use XAMPP on a server. What now?

Packages such as XAMPP bring their own PHP and Apache, often with PHP as an Apache module. Check whether the project offers a version with fixed PHP, and otherwise move the installation to a maintained solution. Such developer packages are not intended for production use anyway.

Sources

Immediate contact

Every hour counts. Write to us now.

Briefly describe your system, PHP version and observation. We will get back to you, clarify the situation and work remotely until the incident is closed and documented.

Immediate help