- Core Issue: PHP version issues occur when the runtime serving web requests or running CLI jobs diverges from your application code, dependencies, or server extensions.
- Security Urgency: The October 2026 security release patched critical vulnerabilities (CVE-2026-109618 and CVE-2026-109619, rated CVSS 9.2) across PHP 8.2 through 8.5; updating system runtime packages is the only full fix.
- Dual-Runtime Rule: Always audit both CLI and FPM runtimes independently before and after patching, because a passing CLI test does not prove your web server or queue workers are safe.
| Metadata | Details |
|---|---|
| Who It Is For | Backend developers, DevOps engineers, and system administrators running PHP web applications on Linux servers. |
| Prerequisites | Basic familiarity with the Linux terminal (ssh, systemctl, grep) and web server architecture (Nginx with PHP-FPM). |
| Estimated Time | 15β20 minutes reading; 10 minutes for read-only diagnostic verification. |
| Difficulty | Intermediate (suitable for developers performing their first server upgrade). |
Introduction
PHP powers 69.3% of websites with a known server-side programming language (W3Techs, October 2026). Keeping the runtime current is one of the most consequential decisions an engineering team makes. A PHP version issue is any situation where the installed PHP runtime is incompatible with, insufficient for, or misconfigured relative to the application it executes.
In web operations, runtime differences emerge across two distinct environments. The Command Line Interface (CLI) is the PHP executable that runs terminal commands and background jobs, whereas FastCGI Process Manager (FPM) is a persistent daemon that handles web requests forwarded by a web server like Nginx. When these two environments diverge, background jobs can succeed while web requests fail with HTTP 500 or 502 errors.
PHP updates matter for security, dependency compatibility, runtime performance, and maintainability. However, not every update automatically boosts speed, and not every outdated version causes an immediate outage. The key is understanding what changed, what risks exist, and how to verify your system safely before and after any change.
This guide explains what PHP version issues are, why they happen, how to recognize them through symptoms, and how to diagnose them with read-only commands. For a copy-pasteable production upgrade workflow, see our companion guide: Fix PHP Version Issues Safely in Staging and Production.
PHP Versioning Explained
PHP uses a major.minor.patch version numbering scheme (for example, 8.4.27), but it does not adhere to strict Semantic Versioning (SemVer). Minor releases can deprecate features and occasionally introduce backward-incompatible modifications; only patch releases are strictly reserved for bug and security fixes.
PHP Version Structure: 8 . 4 . 27
β β βββ Patch: Bug and security fixes only (in-place update)
β βββββββ Minor: Features, deprecations, potential breaks
βββββββββββ Major: Fundamental architecture changes and removals
Major Releases (e.g., 7.4 β 8.0)
Major releases introduce fundamental architecture changes, reworked internal engine APIs, and removals of previously deprecated functionality. For example, legacy constructs such as each() and create_function() were removed in PHP 8.0, causing fatal errors in unmaintained codebases. Migrating across major boundaries requires updating Composer dependencies, refactoring incompatible syntax, and testing in staging. Official migration guides on php.net/docs document every breaking change.
Minor Releases (e.g., 8.3 β 8.4)
Minor releases introduce new language features, performance improvements, and deprecate older functionality. Deprecated features emit warnings (E_DEPRECATED) but continue executing until removed in a future major release. For instance, functions like utf8_encode() and utf8_decode() were deprecated since PHP 8.2 and still present in PHP 8.3 and 8.4. Upgrading across minor versions can also introduce subtle changes in type checking or extension requirements, requiring testing prior to production rollout.
Patch Releases (e.g., 8.4.23 β 8.4.27)
Patch releases fix bugs and security vulnerabilities without altering public APIs or removing language features. They are designed as safe drop-in replacements within the same minor series. Operating system package managers update patch releases in place, preserving binary compatibility for installed extensions.
Support Lifecycle
Each PHP minor release receives two years of active support (bug fixes and security patches) followed by two years of security-only support (critical security updates only). After four years, the branch reaches End of Life (EOL), meaning the official PHP project will never issue another patch for it.
| PHP Branch | Active Support Until | Security Support Until | Current Status (October 2026) |
|---|---|---|---|
| PHP 8.5 | Dec 31, 2027 | Dec 31, 2029 | Active Support |
| PHP 8.4 | Dec 31, 2026 | Dec 31, 2028 | Active Support |
| PHP 8.3 | Dec 31, 2025 | Dec 31, 2027 | Security Support Only |
| PHP 8.2 | Dec 31, 2024 | Dec 31, 2026 | Security Support Only (EOL Dec 31, 2026) |
| PHP 8.1 and older | Ended | Ended | End of Life (No official releases) |
Reference: Official release timeline documented at PHP Supported Versions.
Why CLI and FPM Environments Diverge
On a production Linux server, terminal commands and web requests run through separate executables:
- CLI (
/usr/bin/php): Used by terminal sessions, deployment scripts, cron tasks, and queue workers. Configuration loads from/etc/php/8.4/cli/php.ini. - PHP-FPM (
/usr/sbin/php-fpm8.4): A persistent daemon running worker pools to process HTTP requests forwarded by Nginx. Configuration loads from/etc/php/8.4/fpm/php.iniand pool files in/etc/php/8.4/fpm/pool.d/. - Unix Domain Socket: A Unix domain socket is an inter-process communication endpoint on the local filesystem (such as
/run/php/php8.4-fpm.sock) that allows Nginx and PHP-FPM to exchange HTTP request data without network overhead.
Because CLI and FPM maintain separate binaries, .ini files, and process pools, updating one does not automatically update the other. If an administrator runs an upgrade command that touches only php8.4-cli or fails to reload php8.4-fpm, the terminal will report a newer version while the web server continues serving traffic from the older binary.
Common Causes of PHP Version Problems
Frequently Encountered
- Outdated PHP Runtimes: Running an EOL version means vulnerabilities discovered by security researchers remain unpatched.
- Composer Platform Constraints: Packages declare minimum PHP versions in
composer.json. If the server runtime is below that constraint,composer installrefuses to run. - Missing PHP Extensions: An upgrade to a new minor release requires installing matching extension packages (such as
php8.4-curl,php8.4-mbstring,php8.4-xml). If an extension is missing, classes and functions disappear. - Extension ABI Mismatches on Minor Upgrades: PHP extensions compiled for PHP 8.3 cannot load into PHP 8.4 because internal Zend engine data structures differ. On minor upgrades, extensions must be installed from packages compiled for the target version. On patch upgrades (e.g. 8.4.23 to 8.4.27), extensions update in place via APT.
- CLI vs. FPM Divergence: CLI and web requests use different binaries and configurations. Running a test in the terminal does not prove the web application works.
- Stale Bytecode in OPcache: OPcache is a built-in PHP caching engine that compiles human-readable PHP scripts into bytecode and stores them in shared memory so subsequent requests execute without re-parsing. If PHP-FPM is not gracefully reloaded after an update, workers continue executing stale bytecode from memory.
Less Common but Critical
- Separate
php.iniDirectives:memory_limit,max_execution_time, andupload_max_filesizefrequently differ between CLI and FPM. An upload script may work in CLI testing but fail in FPM. - Nginx Socket Path Mismatches: If upgrading across minor versions (e.g. 8.3 to 8.4), the socket path changes from
/run/php/php8.3-fpm.sockto/run/php/php8.4-fpm.sock. If Nginx is not updated, it returns HTTP 502 Bad Gateway. - Service User and File Permissions: PHP-FPM runs under the unprivileged
www-datauser on Ubuntu. If files or session directories lose appropriate ownership, HTTP 500 errors occur. - Long-Running Background Workers: Queue workers managed by systemd or Supervisor hold the PHP binary in memory. They continue running on the old binary until explicitly restarted.
Symptoms and Their Meaning
When troubleshooting a PHP server, symptoms in error logs provide clear signals:
| Symptom | Probable Causes | Evidence to Collect | Safe Diagnostic Command |
|---|---|---|---|
| HTTP 500 Internal Server Error | Fatal PHP error, missing extension, unhandled exception, syntax error in cached file. | PHP-FPM error log, application error log. | sudo tail -n 50 /var/log/php8.4-fpm.log |
| HTTP 502 Bad Gateway | PHP-FPM daemon inactive, crashed workers, or wrong socket path in Nginx fastcgi_pass. |
Nginx error log, FPM service status. | sudo systemctl status php8.4-fpm |
| Blank White Page | Fatal error with display_errors = Off, or stale bytecode served from memory. |
PHP-FPM error log, application error log. | sudo tail -n 50 /var/log/php8.4-fpm.log |
| Composer Platform Failure | PHP runtime or installed extensions do not satisfy constraints in composer.lock. |
Terminal error during Composer execution. | composer check-platform-reqs |
| Class or Function Not Found | Missing PHP extension, broken autoloader, or removed function (e.g. create_function). |
Stack trace in application log. | php -m and php-fpm8.4 -m |
| API Endpoint Failure | Missing cURL, SOAP, or OpenSSL extension; TLS certificate or handshake change. | Endpoint-specific error logs. | php --ri curl and php --ri soap |
| Queue Worker Crash | Worker daemon executing old binary, memory limit exceeded, unhandled exception. | Supervisor worker log, application error log. | sudo tail -n 50 /var/log/supervisor/laravel-worker*.log |
| Version Discrepancy | CLI binary updated but FPM service was not reloaded, or multiple PHP versions installed. | CLI version output vs FPM version output. | php -v vs sudo php-fpm8.4 -v |
How to Diagnose the Issue
Every diagnostic command below is read-only: it inspects system state without modifying configuration files, database records, or package registries. Run them in order to evaluate your environment.
1. Check the Active CLI Version
What it does: Displays the PHP CLI version and Zend Engine build that executes when typing php in the terminal.
php -v
Expected output (example, your versions and timestamps will differ):
PHP 8.4.27 (cli) (built: Oct 21 2026 12:40:15) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.4.27, Copyright (c) Zend Technologies
with Zend OPcache v8.4.27, Copyright (c), by Zend Technologies
What to do if output differs: If the output shows an older patch level (such as 8.4.23) or an unsupported branch (such as 8.1.30), the CLI binary needs updating via your package manager.
2. Check the PHP-FPM Binary Version
What it does: Displays the version of the PHP-FPM binary on disk used by your web server.
php-fpm8.4 -v
Expected output (example, your versions and timestamps will differ):
PHP 8.4.27 (fpm-fcgi) (built: Oct 21 2026 12:40:15) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.4.27, Copyright (c) Zend Technologies
with Zend OPcache v8.4.27, Copyright (c), by Zend Technologies
What to do if output differs: If CLI reports 8.4.27 but FPM reports 8.4.23, the php8.4-fpm package was not upgraded alongside php8.4-cli.
3. Check Which FPM Services Exist and Run
What it does: Lists all installed systemd service units matching php to detect dual-version installations.
systemctl list-units --type=service 'php*'
Expected output (example, your versions and timestamps will differ):
UNIT LOAD ACTIVE SUB DESCRIPTION
php8.4-fpm.service loaded active running The PHP 8.4 FastCGI Process Manager
What to do if output differs: If you see multiple active services (e.g., both php8.2-fpm and php8.4-fpm), verify which socket your web server actually points to.
4. Validate Web Server Service Status
What it does: Confirms whether PHP-FPM and Nginx are actively running.
sudo systemctl is-active php8.4-fpm nginx
Expected output (example, your versions and timestamps will differ):
active
active
What to do if output differs: If either service reports inactive or failed, inspect systemd failure logs:
sudo systemctl --failed
sudo journalctl -u php8.4-fpm -n 50 --no-pager
5. Validate Nginx Configuration Syntax
What it does: Tests the Nginx configuration files for syntax errors and validates referenced paths without restarting the server.
sudo nginx -t
Expected output (example, your versions and timestamps will differ):
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
What to do if output differs: Open the file referenced in the error message (e.g., /etc/nginx/sites-available/default) and correct the invalid directive or broken socket path.
6. Inspect Loaded CLI and FPM Extensions
What it does: Lists compiled-in and dynamically loaded PHP modules for both CLI and FPM environments.
# Check CLI modules
php -m
# Check FPM modules directly
sudo php-fpm8.4 -m
Expected output (example, your versions and timestamps will differ): A clean list of installed modules including Core, date, pcre, zlib, curl, mbstring, openssl, Zend OPcache, and application-specific modules like pdo_mysql or redis.
What to do if output differs: If an extension appears in CLI but is missing from FPM, check whether its .ini file is present in /etc/php/8.4/fpm/conf.d/.
7. Inspect Specific Extension Configuration
What it does: Uses PHP extension reflection (--ri) to display detailed configuration and version data for a specific extension without piping through grep.
php --ri redis
Expected output (example, your versions and timestamps will differ):
redis
Redis Support => enabled
Redis Version => 6.1.0
What to do if output differs: If output states Extension 'redis' not present, install the matching package:
sudo apt-get install php8.4-redis
8. Verify Composer Platform Requirements
What it does: Compares the local PHP runtime and loaded extensions against every package constraint declared in composer.lock.
cd /var/www/your-app && composer check-platform-reqs
Expected output (example, your versions and timestamps will differ):
Checking platform requirements for packages in the vendor dir
ext-curl 8.4.27 success
ext-mbstring 8.4.27 success
ext-openssl 8.4.27 success
php 8.4.27 success
What to do if output differs: If any requirement reports failed, Composer identifies the exact package constraint violated. Do not run composer update on a live server; resolve the missing system extension or update the codebase in staging. Reference: Composer Platform Check Documentation.
9. Verify the Running Master Process Binary in /proc
What it does: Inspects the /proc virtual filesystem for the running PHP-FPM master PID to confirm that the active process in memory matches the updated on-disk binary rather than executing an unlinked binary.
sudo ls -l /proc/$(systemctl show -p MainPID --value php8.4-fpm)/exe
Expected output (example, your versions and timestamps will differ):
lrwxrwxrwx 1 root root 0 Oct 21 13:05 /proc/12345/exe -> /usr/sbin/php-fpm8.4
What to do if output differs: If the path ends with (deleted) (for example /usr/sbin/php-fpm8.4 (deleted)), the master process is still executing the old binary from unlinked memory after a package upgrade. Run sudo systemctl reload php8.4-fpm (or restart) to refresh the daemon. Note that on Ubuntu, after apt upgrades, needrestart may already restart services automatically; still verify with this /proc check.
Security and Compatibility Risks
The 48-Hour Incident: Leak, Emergency Release, and Remediation
In late October 2026, the PHP development team issued emergency patch releases to address two critical security vulnerabilities in the core engine.
OCT 20: Pre-Disclosure Circulation
ββ CVE IDs (CVE-2026-109618, CVE-2026-109619), a wrong release time, and a wrong 10.0 score
circulated on social channels; the PHP Foundation confirmed that no technical details leaked.
OCT 21: Coordinated Security Patch Releases
ββ Official security patch releases shipped across all active branches:
PHP 8.5.12, 8.4.27, 8.3.36, and 8.2.35. Official rating: CVSS v4.0 9.2 (Critical).
OCT 22: Operations & Deployment Verification
ββ Production teams apply targeted OS package updates and reload PHP-FPM workers.
The vulnerabilities patched across supported branches are:
- CVE-2026-109618 (GHSA-w8hw-w9fx-j79w, CVSS v4.0: 9.2 β "RCE via OOM corruption"): PHP uses
longjmp()on out-of-memory (OOM) errors to abort handling of the request. In some contexts, request memory is temporarily reachable before it is fully initialized. If an allocation fails at that point, PHP does not properly account for the early exit and leaves request memory in an invalid state that the request shutdown procedure can subsequently read or branch on, leading to remote code execution (RCE). Several multipart parsing problems (such as requests without a usable declared content length, unrestricted headers per part, or nested array inputs) provide mechanisms to reach OOM while remaining within apparent limits. Exploitation was validated against Apachemod_php, which unconditionally invokes request shutdown. For PHP-FPM, source analysis supports FPM as susceptible, though no complete FPM exploit has been demonstrated for that SAPI. - CVE-2026-109619 (GHSA-6wmf-4rv5-p3rp, CVSS v4.0: 9.2 β "RCE via stale global state"): Global state (error, session, object, extension state) retained by a worker points to memory owned by an earlier request; a later request handled by the same worker can use it after free. RCE was validated against
mod_phpand against PHP-FPM via the session upload progress lifecycle path.
Amazon Threat Intelligence observed an exploitation attempt against its honeypot network on October 17, four days before public disclosure, as reported by Tenable.
Fixed Releases Table
Updating system packages to the fixed release is the only complete and permanent remediation:
| Branch | Fixed Release | Official Release Date | Maintenance Status |
|---|---|---|---|
| PHP 8.5 | 8.5.12 | October 21, 2026 | Active Support |
| PHP 8.4 | 8.4.27 | October 21, 2026 | Active Support |
| PHP 8.3 | 8.3.36 | October 21, 2026 | Security Support |
| PHP 8.2 | 8.2.35 | October 21, 2026 | Security Support (EOL Dec 2026) |
| PHP 8.1 & older | No official release; the PHP security team published source-only backports for older branches (see Tenable FAQ) | β | End of Life (No official security patches) |
Primary Sources:
- PHP 8.4.27 Release Announcement
- GHSA-w8hw-w9fx-j79w Advisory (CVE-2026-109618)
- GHSA-6wmf-4rv5-p3rp Advisory (CVE-2026-109619)
- PHP Supported Versions
Interim Configuration Mitigations
Updating to a PHP release containing the patch is the only complete and reliable mitigation. There is no complete generic configuration mitigation for either vulnerability. Each official advisory explicitly notes to also follow the remediation advice from the related report: link both GHSA-w8hw-w9fx-j79w and GHSA-6wmf-4rv5-p3rp.
If a production server cannot be upgraded immediately due to a deployment freeze or change window constraint, interim configuration mitigations can reduce attack surface. The official GitHub Security Advisories (GHSA-w8hw-w9fx-j79w and GHSA-6wmf-4rv5-p3rp) advise upgrading as the only complete solution, but outline the following partial stopgaps:
- For CVE-2026-109618 (OOM Mitigation β GHSA-w8hw-w9fx-j79w):
- Setting and enforcing
memory_limit = -1administratively in/etc/php/8.4/fpm/php.iniis the primary configuration stopgap (it removes the predictable per-request limit that enables a controllable OOM). -
Setting
memory_limit = -1removes PHP's own memory cap; ensure underlying system memory is monitored. Ifmmap()or another underlying allocation fails, PHP can still uselongjmp(). Do not useRLIMIT_ASorRLIMIT_DATA, as these causemmap()to fail once the limit is reached, triggering the vulnerablelongjmp()path. - Keep
post_max_sizeconservative and independently enforce the decoded request size at the frontend. - Reduce
max_input_nesting_level, and bound the number of input variables, multipart parts, headers within each part, and uploads. - If the application does not use multipart form data, block such requests at the frontend reverse proxy before they reach PHP.
- Setting and enforcing
- For CVE-2026-109619 (Global State Mitigation β GHSA-6wmf-4rv5-p3rp):
- Disable session upload progress (settings documented by The Hacker News): in
/etc/php/8.4/fpm/php.ini, set:session.upload_progress.enabled = 0 - On PHP 8.5 installations, additionally disable fatal error backtraces (documented by The Hacker News):
fatal_error_backtraces = 0 - Restart every PHP worker process:
sudo systemctl reload php8.4-fpm - Eliminate the fatal errors and warnings themselves on attacker-reachable paths. Hiding or not logging them (error_reporting, @, display_errors, log_errors) does not protect against CVE-2026-109619.
- If performance is not a factor, consider limiting requests per worker using
pm.max_requests = 1.
- Disable session upload progress (settings documented by The Hacker News): in
Composer Updates vs. PHP Runtime Updates
A frequent misconception among application developers is that running composer update patches PHP security flaws.
| Layer | Tool | What It Updates | Protects Against |
|---|---|---|---|
| Userland Application | Composer (composer update) |
PHP files in vendor/ (frameworks, packages, libraries). |
Application-level vulnerabilities (e.g. SQL injection in an ORM). |
| System Runtime | APT (apt-get install --only-upgrade) |
Compiled C binaries (/usr/bin/php, /usr/sbin/php-fpm8.4). |
Engine-level vulnerabilities (e.g. memory corruption, buffer overflows, RCE). |
Composer modifies userland PHP source code inside your application repository. It cannot update compiled C binaries running inside the operating system. When an engine-level CVE is announced, running composer update does not patch the vulnerability; you must upgrade the system package via APT and reload the FPM daemon.
Case Study: PHP 8.4.23 to 8.4.27 on Ubuntu 24.04
Here is an account of the upgrade I conducted.
Environment
- Operating System: Ubuntu 24.04 LTS
- Web Stack: Nginx + PHP-FPM
- Application Architecture: Composer-managed PHP application (API and web frontend)
- Initial Runtime: PHP 8.4.23
- Target Runtime: PHP 8.4.27
Upgrade Execution
-
Checked Upgrade Candidate: I checked the candidate version in the configured repository to confirm that PHP 8.4.27 was available.
-
Upgraded Packages Through APT: I upgraded PHP from 8.4.23 to 8.4.27 through APT. All related PHP 8.4 packages (CLI, FPM, common, and installed extensions) were upgraded together.
-
Installed
php8.4-redisExtension in Same Window: I installedphp8.4-redisin the same window to support a planned cache migration. -
Post-Upgrade Verification: I verified the runtime and application health:
php -vshowed 8.4.27- PHP-FPM was active
- Nginx was active
nginx -tpassed- Application config and bytecode caches were rebuilt
- The HTTPS homepage returned HTTP 200
- The HTTP to HTTPS redirect returned HTTP 301
Separate Change: Redis Cache Migration
Afterwards, as a separate change:
- Redis was installed and configured.
- The cache backend was moved from the database cache table to Redis (dedicated connection, Redis database 1).
- Read/write tests passed.
Historical Application Log Entry
A July 4, 2026 application log entry reported that a database cache table did not exist; later checks confirmed the table exists.
Out of Scope: Integration Environment
A separate integration environment with SOAP and third-party sync APIs was not in scope and would need its own regression testing.
Lessons Learned
- A PHP patch upgrade (within the same minor version) on a well-maintained server is typically low-risk, but verification is still required.
- Cache backend migrations and PHP runtime upgrades are independent changes and should be treated as separate operations with separate verification.
- Historical log entries should be investigated on their own timeline rather than attributed to a recent change without evidence.
- Confirming the homepage responds does not constitute full validation β critical integrations, APIs, queue workers, and scheduled jobs need separate checks.
Developer Checklist
Use this checklist during runtime diagnostic reviews:
- Check active CLI binary:
php -v - Check installed FPM binary:
php-fpm8.4 -v - Verify both services are active:
sudo systemctl is-active php8.4-fpm nginx - Verify Nginx syntax:
sudo nginx -t - Audit loaded extensions:
php -mandsudo php-fpm8.4 -m - Verify Composer lockfile constraints:
composer check-platform-reqs - Verify running process binary in
/proc - Inspect error logs:
sudo tail -n 50 /var/log/php8.4-fpm.log
Glossary of Key Terms
- CLI (Command Line Interface): The PHP executable binary that runs in terminal sessions, cron jobs, and background workers.
- CVSS (Common Vulnerability Scoring System): A standardized 0.0 to 10.0 framework used by security researchers to quantify vulnerability severity.
- Dry Run: A simulation mode (such as
apt-get upgrade --dry-run) that computes package dependency changes without modifying the filesystem. - EOL (End of Life): The official date after which a software release receives no further security patches or bug fixes from maintainers.
- FPM (FastCGI Process Manager): A high-performance PHP FastCGI daemon that manages worker pools to process web requests.
- OPcache: A core PHP extension that compiles script source code into shared-memory bytecode to accelerate execution.
- Package Hold: Instructing the operating system package manager (via
apt-mark hold) to lock a package at a specific version to prevent unintended updates. - Version List: A recorded baseline file (generated via
dpkg-query) listing installed package names and exact versions, used for verification and rollback safety. - RCE (Remote Code Execution): A critical vulnerability that allows an attacker to execute arbitrary commands or code on a target server over the network.
- Unix Domain Socket: A local filesystem inter-process communication endpoint (e.g.
/run/php/php8.4-fpm.sock) enabling high-speed data exchange between Nginx and PHP-FPM.
Frequently Asked Questions (FAQ)
How do I find the PHP version used by the website?
Do not rely solely on php -v in the terminal. The CLI binary and the web server runtime are independent. To find the exact PHP version handling web requests, check your web server configuration (such as the Nginx fastcgi_pass directive in /etc/nginx/sites-enabled/) to see which PHP-FPM socket or port it connects to, or query the running PHP-FPM binary directly using php-fpm8.4 -v and inspect the active master process in /proc.
Why do php -v and the web runtime sometimes differ?
On Linux systems like Ubuntu, the PHP CLI (/usr/bin/php) and PHP-FPM (/usr/sbin/php-fpm8.4) are distributed as separate packages with distinct binaries and separate configuration trees (/etc/php/8.4/cli/php.ini vs /etc/php/8.4/fpm/php.ini). The terminal php command may point to an older or default version via /etc/alternatives/php, while Nginx passes web traffic to a specific versioned PHP-FPM pool socket.
Is every PHP update safe?
Patch releases (such as 8.4.23 to 8.4.27) are designed to be fully backward-compatible drop-in replacements that contain only bug fixes and security patches. However, minor releases (such as 8.3 to 8.4) introduce deprecations, modify function behaviors, and change Zend internal extension APIs. Always test minor upgrades thoroughly in a staging environment that mirrors production before upgrading.
Do PHP extensions need to be upgraded too?
Yes. Compiled C extensions (such as php8.4-curl, php8.4-mbstring, php8.4-redis, php8.4-opcache, and database drivers) are compiled against specific PHP internal API versions. When performing minor upgrades, extensions must be updated to match the new PHP version. During patch upgrades, package managers like APT update installed extension packages alongside the core runtime.
How do I tell whether an error is caused by PHP or application code?
Check the logs systematically across three tiers. PHP-level errors (such as missing extensions, segmentation faults, or php.ini syntax issues) appear in the PHP-FPM error log (/var/log/php8.4-fpm.log). Web proxy issues (such as HTTP 502 Bad Gateway when FPM is down or socket permissions fail) appear in the web server error log (/var/log/nginx/error.log). Unhandled exceptions, database query errors, and framework fatal errors appear in your application error log (storage/logs/laravel.log).
Should I update staging before production?
Always. Staging must mirror production as closely as possible β matching OS version, PHP version, compiled extensions, and configuration directives. Testing the upgrade in staging verifies that your package manager transactions, configuration syntax, automated test suites, and critical application workflows succeed before touching production servers.
How do I verify an update without relying on one homepage request?
A successful homepage HTTP 200 response only proves that basic routing works; it does not exercise database writes, background workers, or extensions. Proper verification requires: executing automated test suites, validating lockfile constraints with composer check-platform-reqs, testing authenticated user workflows and file uploads, verifying that background queue workers have restarted with the new runtime binary, and actively monitoring error logs during post-deployment traffic.
Next Steps
Now that you understand PHP runtime architecture and diagnostic verification, review our complete production runbook: Fix PHP Version Issues Safely in Staging and Production.
Sources and Official References
- PHP 8.4.27 Release Announcement: https://www.php.net/releases/8_4_27.php
- PHP Core Security Advisories: https://github.com/php/php-src/security/advisories
- Tenable Security Analysis (Pre-Disclosure Exploitation FAQ): https://www.tenable.com/blog/php2shell-cve-2026-109618-cve-2026-109619-frequently-asked-questions-about-critical-php-remote
- The Hacker News Emergency Patches & Interim Mitigation Report: https://thehackernews.com/2026/10/php-issues-emergency-patches-for-two.html
- PHP Supported Versions & EOL Calendar: https://www.php.net/supported-versions.php
- W3Techs Server-Side Programming Languages Survey (2026): https://w3techs.com/technologies/details/pl-php
- Composer Platform Check Documentation: https://getcomposer.org/doc/06-config.md#platform-check