
On 20 October 2026 the PHP security team announced an out-of-cycle release for Wednesday 21 October at 14:00 UTC, fixing two vulnerabilities it rates CVSS v4.0 9.2. Before you can patch, you need to check PHP version numbers on every runtime you own, and that is rarely one number. A typical Linux web server has a CLI binary, a php-fpm service (sometimes two), maybe an Apache module, plus containers and a forgotten php.exe inside some Windows tool. Running php -v once tells you about exactly one of those.
This guide is the practical half of the response: find each PHP, read its version correctly (distro packages make that tricky), upgrade it, restart the right service and prove the change reached the web server. Every command below was run on the versions noted, or is marked untested.
Status at 11:28 UTC on 21 October 2026: the fixes were not yet published. Current releases on php.net are 8.5.11, 8.4.26, 8.3.35 and 8.2.34 (all from 24 September). PHP says affected and fixed versions will be published with the release, and only the supported branches 8.2 to 8.5 get them. Until then, the official minimum safe version per branch is unknown; a patched build will be a version newer than the 24 September release for your branch, or a distro package whose changelog names the new CVE ids. Ignore version numbers you see in social posts until php.net lists them.
The short checklist
- List every PHP binary and running PHP process on each server (CLI, php-fpm, php-cgi, Apache module).
- Ask the web server which PHP it actually runs: php-fpm
-v, the loaded Apache module, or a temporaryphpinfo()page that you delete straight away. - List containers and images that ship PHP, including base images in your Dockerfiles.
- On hosting panels and WordPress, read the per-site PHP version from the panel or Site Health.
- Search Windows machines for bundled
php.exeandphp-cgi.exe. - When php.net publishes the release, compare each runtime against the fixed version for its branch, or against your distro's advisory.
- Upgrade, restart php-fpm and the web server, then re-check from the web side.
Why one server can report three PHP versions
PHP ships as several front ends, called SAPIs, built from the same source. Package managers install them separately, so they can drift apart. If someone added a newer CLI for Composer but left the old FPM pool in place, the terminal and the website disagree.
| Runtime | What it serves | How it reports itself |
|---|---|---|
php (CLI) | Cron jobs, Composer, artisan/wp-cli | php -v shows (cli) |
php-fpm | Web requests via nginx or Apache proxy | php-fpm -v shows (fpm-fcgi) |
| Apache module (mod_php) | Web requests inside Apache | phpinfo "Server API: Apache 2.0 Handler" |
php-cgi | CGI/FastCGI setups, many Windows stacks | php-cgi -v shows (cgi-fcgi) |
| Container image | Whatever the image runs | Same commands, inside the container |
How to check PHP version on a Linux server
To check PHP version from the command line on Linux, start with the CLI, then work through the web-facing pieces. Each output below is from the official Docker images (Debian 13 based) on 21 October 2026.
The CLI and its config
php -v
php -r 'echo PHP_VERSION, " ", PHP_SAPI, PHP_EOL;'
php --iniTested on php:8.5-cli: PHP 8.5.11 (cli) (built: Oct 21 2026 00:25:28) (NTS), then 8.5.11 cli, then the php.ini search path. The -r one-liner is handy in scripts because it prints only the number and the SAPI name.
php-fpm and its pools
php-fpm -v # Debian/Ubuntu: php-fpm8.4 -v Alpine: php-fpm84 -v
php-fpm -t # test the config
php-fpm -tt # test and print the effective config, pool by poolTested on php:8.4-fpm: PHP 8.4.26 (fpm-fcgi). The -tt output names each pool ([www]) with its listen address, which is how you spot a second pool nobody remembers. On Debian the binary carries the branch in its name (/usr/sbin/php-fpm8.4, pools in /etc/php/8.4/fpm/pool.d/), so a box with php-fpm8.2 and php-fpm8.4 runs two separate services. On RHEL, Alma and Rocky the service is plain php-fpm with pools in /etc/php-fpm.d/.
Apache with mod_php
apache2ctl -M 2>/dev/null | grep -i php # RHEL family: httpd -M
ls /etc/apache2/mods-enabled | grep -i phpTested on php:8.3-apache: php_module (shared) and php.load. Debian's own package names the file after the branch (php8.4.load), which tells you the version at a glance. httpd -M untested.
Every PHP binary on disk, and every running one
find / -xdev -type f \( -name php -o -name 'php[0-9]*' -o -name 'php-fpm*' -o -name 'php-cgi*' \) 2>/dev/null
for p in /proc/[0-9]*; do e=$(readlink "$p/exe" 2>/dev/null); case "$e" in *php*) echo "${p#/proc/} $e";; esac; doneThe first command found /usr/local/bin/php and /usr/local/bin/php-cgi in php:8.5-cli (plus a man page, which you can ignore). -xdev stays on one filesystem, so repeat it for other mounts such as /opt or /srv. The /proc loop works even where ps is missing; in php:8.4-fpm it printed 1 /usr/local/sbin/php-fpm. Run it as root to see every user's processes. If these one-liners look dense, our guide to pipes and grep walks through the pieces.
update-alternatives only covers the CLI
update-alternatives --display php
sudo update-alternatives --config phpOn Debian and Ubuntu, /usr/bin/php is an alternatives link to one of /usr/bin/php8.x. Switching it changes the terminal only, never php-fpm or Apache. On a box without PHP packages, the command answers update-alternatives: error: no alternatives for php (tested on ubuntu:24.04). Output with several PHP packages installed: untested.
Ask the web server directly
The only answer that matters for an internet-facing site is what the web server executes. A temporary phpinfo() page settles it. Give it an unguessable name and delete it in the same session, because phpinfo output is a gift to attackers.
cd /var/www/html
name="pi-$(openssl rand -hex 8).php"
echo '<?php phpinfo(INFO_GENERAL);' | sudo tee "$name" >/dev/null
curl -s "http://localhost/$name" | grep -oE 'PHP Version [0-9.]+'
sudo rm -f "$name"Tested on php:8.3-apache (as root, so without sudo): it printed PHP Version 8.3.35, the page showed "Server API: Apache 2.0 Handler", and the URL returned 404 after the rm. Use the vhost's real hostname if localhost points elsewhere, and repeat per site when sites use different pools.
Docker images and running containers
docker run --rm php:8.4-fpm php -v
docker image inspect php:8.4-fpm --format '{{range .Config.Env}}{{println .}}{{end}}' | grep PHP_VERSION
for c in $(docker ps -q); do
n=$(docker inspect -f '{{.Name}} {{.Config.Image}}' "$c")
v=$(docker exec "$c" php -r 'echo PHP_VERSION;' 2>/dev/null) && echo "$n: PHP $v" || echo "$n: no php on PATH"
doneTested with Docker 29.1.2: the official images report 8.5.11, 8.4.26 and 8.3.35, and image inspect prints PHP_VERSION=8.4.26 without starting a container. The loop listed each running container with its PHP version and marked nginx and Postgres containers as having none. Alpine images that install distro PHP name the binary php84, so add that name if your images use it.
A gotcha worth knowing: the php:8.5-cli image on this machine was built at 00:26 UTC on 21 October, yet still contains 8.5.11. Official images are rebuilt often for base OS updates, so a fresh build date does not mean patched PHP. Check the PHP version, not the image age.
No shell? cPanel, Plesk and WordPress
- cPanel: to check PHP version in cPanel, open MultiPHP Manager. The domain list shows the version each domain uses, an "Inherited" label when it follows the server default, and whether PHP-FPM is on. Only the server administrator sets the system default, in WHM's MultiPHP Manager (cPanel docs).
- Plesk: Tools & Settings > PHP Settings lists each installed version and handler; new versions come from Tools & Settings > Updates and Upgrades. Menu names may differ slightly between Plesk releases.
- WordPress: to check PHP version in WordPress, go to Tools > Site Health > Info and expand Server. WordPress core labels the rows "PHP version" and "PHP SAPI", so you see both the number and how it runs (Site Health docs).
On shared hosting your host patches the PHP builds; your job is to make sure each site is set to a supported branch (8.2 or newer) so it receives the fix. Before switching a WordPress site to a newer branch, back up the site with UpdraftPlus or your host's backup tool.
Check PHP version in cmd and PowerShell on Windows
Windows is where PHP hides: XAMPP, WAMP and similar bundles, as well as vendor tools, can ship their own copy. This PowerShell search reads the version from each file's metadata, so nothing gets executed:
Get-ChildItem -Path C:\ -Recurse -Include php.exe, php-cgi.exe -ErrorAction SilentlyContinue |
ForEach-Object { "{0} {1}" -f $_.VersionInfo.ProductVersion, $_.FullName }To check PHP version in cmd for the copy on your PATH:
where.exe php
php -v
php -i | findstr /C:"Thread Safety" /C:"Architecture" /C:"Loaded Configuration File"Tested on Windows 11 (PowerShell 5.1) with the official 8.5.11 NTS x64 zip: the search printed 8.5.11 next to both php.exe and php-cgi.exe; php -v printed PHP 8.5.11 (cli) (built: Sep 22 2026 13:51:38) (NTS Visual C++ 2022 x64); findstr showed Thread Safety => disabled and Architecture => x64. Note those two values: a replacement build must match them. Scanning all of C:\ can take minutes on a large disk. For XAMPP, the bundled phpinfo page also shows which php.ini is loaded, and Apache must be restarted after changes.
Is that version patched? Read the distro number
Upstream numbers tell the whole story for builds from php.net, the official Docker images, Remi and Alpine, whose package versions currently match php.net's point releases. Some distros backport fixes into an older base version instead. As of today, Launchpad lists Ubuntu 24.04's package as 8.3.6-0ubuntu0.24.04.12: the upstream number says 8.3.6, but the .12 revision carries security fixes applied since. Ubuntu 22.04 likewise ships 8.1.2-1ubuntu2.27, a branch php.net no longer supports but Ubuntu still patches. Debian stable currently tracks point releases through its security archive (bookworm security has 8.2.34-1~deb12u1, trixie security 8.4.26-1~deb13u1).
So for distro packages, a php security update is confirmed by the CVE ids, not the number:
dpkg -l 'php*' | grep ^ii
apt-cache policy php8.3-fpm
apt-get changelog php8.3-common | grep -n 'CVE-2026-'
zgrep -n 'CVE-2026-' /usr/share/doc/php8.3-common/changelog.Debian.gz
rpm -q --changelog php-common | grep -n 'CVE-2026-' # RHEL familyPartly tested: on ubuntu:24.04 the dpkg -l pattern and the zgrep changelog search worked against an installed package (bash), and apt-get changelog exists but needs network. The PHP package names and the rpm line are untested here. The CVE ids researchers are using for these two flaws are CVE-2026-109618 and CVE-2026-109619; PHP's notice does not name them, and by 11:20 UTC none of the Debian, Ubuntu or Red Hat trackers had an entry. Watch Debian's security tracker, Ubuntu security notices and Red Hat's CVE database for them.
For upstream-numbered builds, compare against the official minimum once php.net publishes it:
MIN=8.4.26 # replace with the official fixed version for your branch
php -r 'exit(version_compare(PHP_VERSION, $argv[1], ">=") ? 0 : 1);' "$MIN" && echo "OK" || echo "UPGRADE NEEDED"Tested on php:8.4-fpm: with MIN=8.4.26 it printed OK, with a higher dummy value it printed UPGRADE NEEDED. Do not use this check on backported Ubuntu packages; it will flag them forever.
Upgrade PHP version on each platform
To upgrade PHP version safely, stay on your branch for the security fix (8.3 to the next 8.3) and plan branch jumps separately; a jump can break extensions and plugins. Builds older than 8.2 will not get an upstream fix at all, which our companion guide on end-of-life PHP covers.
Debian and Ubuntu packages
This is the usual way to upgrade PHP version on Ubuntu or Debian when you use the distro's own packages:
sudo apt update
apt list --upgradable 2>/dev/null | grep -i php
sudo apt install --only-upgrade php8.3-cli php8.3-fpm php8.3-commonUntested here (no package network in the test containers). Adjust the branch and add each php8.3-* extension package you have, or run a full sudo apt upgrade.
Sury (Debian) and ondrej/php (Ubuntu)
Ondřej Surý's repositories publish upstream point releases for several branches side by side. The Launchpad PPA is still offered for Ubuntu 22.04 and 24.04, while 26.04 users are pointed to packages.sury.org, which has a setup script in its README. These are third-party repositories. If you already use one, the same apt update and upgrade steps pick up new builds once they are published.
sudo add-apt-repository ppa:ondrej/php
sudo apt updateUntested.
RHEL, AlmaLinux and Rocky
Red Hat ships PHP as AppStream packages and module streams (RHEL 9 docs list 8.0 as the default package with 8.1 and 8.2 streams; Remi's wizard reports 8.0 to 8.3 for EL 9 and 8.3 for EL 10). Distro updates arrive through normal dnf. For current upstream versions, Remi's repository is the common route:
dnf module list php
sudo dnf upgrade 'php*'
# Remi, EL 9 (use remi-release-10.rpm on EL 10)
sudo dnf install https://rpms.remirepo.net/enterprise/remi-release-9.rpm
sudo dnf module switch-to php:remi-8.4
php --versionUntested. The Remi commands are from the Remi configuration wizard, which also lists the EPEL and CRB steps for your release; switch-to upgrades or downgrades an installed stream.
Alpine
apk info -vv | grep '^php'
sudo apk update && sudo apk upgrade php84 php84-fpm
php84 -vAlpine 3.24 currently carries php83, php84 and php85 packages at 8.3.35, 8.4.26 and 8.5.11. The listing and the apk upgrade syntax were checked on Alpine 3.24.2 (apk-tools 3.0.8); the upgrade itself is untested. Fixes show up in Alpine's secdb.
Docker
docker build --pull --no-cache -t myapp:patched .
docker compose build --pull && docker compose up -d--pull makes the build fetch the newest base image instead of reusing the cached one; --no-cache stops old layers from surviving. Pin a branch tag such as php:8.4-fpm (tags listed on Docker Hub) rather than an exact patch tag, or bump the exact tag when the release lands. Flags verified with --help on Docker 29.1.2; a rebuild against the new release is untested.
Windows
Download the new build from windows.php.net, matching thread safety (TS/NTS), architecture and compiler (VS17) to your current copy, and verify the SHA-256 shown on the page:
Get-FileHash .\php-8.5.11-nts-Win32-vs17-x64.zip -Algorithm SHA256Tested: the hash matched the value published for 8.5.11. Keep your php.ini and extension list, replace the folder, and restart IIS, Apache or the service that hosts PHP. For bundles like XAMPP, replace the bundle's PHP folder or move to a newer bundle; vendor tools need the vendor's update.
Restart, then prove the web server changed
The step most often missed: a package upgrade swaps files on disk, but a running php-fpm master or an Apache process with mod_php keeps the code it loaded at start. Some packages restart the service for you; do not rely on it.
sudo systemctl restart php8.4-fpm # Debian/Ubuntu, one per installed branch
sudo systemctl restart apache2 # mod_php, or Apache proxying to FPM
sudo systemctl restart php-fpm httpd # RHEL, Alma, Rocky
sudo systemctl reload nginx
sudo rc-service php-fpm84 restart # Alpine (OpenRC)Untested (no systemd in the test containers); unit names come from the Debian package file list, Red Hat's docs and Alpine's package contents. Then repeat the web-side check: php-fpm8.4 -v, the temporary phpinfo page, or Site Health. Done means the web server reports the fixed version, not the terminal.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Terminal shows the new version, site shows the old one | CLI upgraded, FPM or mod_php not; or service not restarted | Upgrade the -fpm/Apache package for that branch and restart it |
update-alternatives switched but nothing changed on the site | Alternatives only move /usr/bin/php | Point the vhost or pool at the new FPM socket |
| Ubuntu still says 8.3.6 after upgrading | Backported package | Check the changelog and USN for the CVE ids |
| Container rebuilt, still old PHP | Cached base image or pinned patch tag | docker build --pull --no-cache, bump the tag |
| Site errors after a branch switch | Extensions not installed for the new branch | Install the matching php8.x-* packages; see our fix for the missing MySQL extension error |
| New php.exe will not start | Missing Visual C++ Redistributable 2015-2022, or wrong TS/NTS build | Install the redistributable; match the build to the old one |
FAQ
Why does php -v show a different version from my website?
The terminal runs the CLI binary; the website runs php-fpm, mod_php or php-cgi, which are installed and restarted separately. Check the web side with php-fpm -v, the Apache module list or a temporary phpinfo page.
Which PHP versions fix php2shell?
At 11:28 UTC on 21 October 2026 php.net had not published them. The fixes are scheduled for 14:00 UTC and only for 8.2, 8.3, 8.4 and 8.5. This post will be updated with the official numbers.
My Ubuntu server reports PHP 8.3.6. Is it unpatched?
Not necessarily. Ubuntu backports security fixes, so the full package version (for example 8.3.6-0ubuntu0.24.04.12) matters. Look for the CVE ids in the package changelog or Ubuntu's security notices.
How do I check PHP version without SSH?
Use your hosting panel (cPanel MultiPHP Manager or Plesk PHP Settings) or, on WordPress, Tools > Site Health > Info > Server.
Do I have to restart anything after upgrading?
Yes. Restart each php-fpm service and Apache if it loads mod_php, then confirm from the web side.
For background on the flaws themselves, see our companion php2shell explainer; for what to do on 5.x, 7.x, 8.0 or 8.1, our end-of-life PHP guide; and for checking a server for web shells, our detection guide.
If you would rather have someone handle the upgrade, our studio, Pravinya Studio, takes on PHP version upgrades, WordPress plugin and theme compatibility fixes, and testing older PHP apps on a supported version.
Last updated / tested on: 21 October 2026, 11:28 UTC (last php.net check; the security release was not out yet). Commands tested on official Docker images php:8.5-cli 8.5.11, php:8.4-fpm 8.4.26, php:8.3-apache 8.3.35, ubuntu:24.04, Alpine 3.24.2 and Windows 11 with PHP 8.5.11. This post will be updated with the official fixed versions once php.net publishes them.