# How to upgrade PHP 7.4 / 8.1 to 8.4 without breaking production

> A practical guide to upgrading PHP 7.4, 8.1 or 8.2 to 8.4 on custom systems: inventory, Composer, what breaks in each version, testing and staged rollout.

Author: Samuel Hinojosa (CEO & Founder, WITS) · Updated: 2026-10-25 · https://security.wits.mx/en/guides/upgrade-php-8-4/

## Why upgrade PHP now?

Because PHP 8.1 stopped receiving security fixes on December 31, 2025, and PHP 8.2 loses them on December 31, 2026. PHP 7.4 has been unsupported since November 2022. When a serious flaw ships, those branches get no official fix. PHP 8.4 receives security fixes until December 31, 2028, which buys you two more years.

This isn't a paperwork deadline. In October 2026 [PHP2Shell](https://security.wits.mx/en/guides/php2shell-cve-2026-109618/) landed, a critical flaw that lets an outsider take over a server without a password. Supported branches got a fix the same day. PHP 7.4, 8.0 and 8.1 didn't: teams still on them are relying on distribution packages, a backport, or an emergency upgrade. The dates below come from PHP's [supported versions table](https://www.php.net/supported-versions.php) and its [list of unsupported branches](https://www.php.net/eol.php).

| Branch | Security fixes until | Status as of Oct 25, 2026 |
|---|---|---|
| 7.4 | Nov 28, 2022 | end of life |
| 8.0 | Nov 26, 2023 | end of life |
| 8.1 | Dec 31, 2025 | end of life |
| 8.2 | Dec 31, 2026 | security only, weeks left |
| 8.3 | Dec 31, 2027 | security only |
| 8.4 | Dec 31, 2028 | active support until Dec 31, 2026 |
| 8.5 | Dec 31, 2029 | active support |

> **Why 8.4 and not 8.5?** Both are supported. For a legacy system, 8.4 is usually the most practical target: it has been in production for almost a year, libraries support it and it carries you to 2028. If your code and dependencies already run on 8.5, go for it. What we'd avoid is stopping at 8.3, which loses security fixes in 2027 and puts you back in the same project soon.

## What breaks when you go from PHP 7.4 to 8.4?

Most of the work is in the first jump, from 7.4 to 8.0. Later versions mostly add deprecation notices: they don't break the system right away, but they flood the logs and become hard errors in future releases. Here's a summary of PHP's official migration guides, weighted toward what we see fail most in business applications.

### 7.4 to 8.0: the big jump

- Number-to-string comparisons: «0 == "foo"» is now false. Forms that submit empty fields compared against 0 change behavior without any error.
- Removed functions: «each()», «create_function()», «money_format()», «get_magic_quotes_gpc()» and others. The code fails with «undefined function».
- Many warnings are now exceptions: «count()» on something that isn't countable, or arithmetic on arrays, throws «TypeError». What used to pass silently now stops the page.
- The «@» operator no longer hides fatal errors and «error_reporting» defaults to «E_ALL». Make sure «display_errors» is off in production.
- «match» and «mixed» are reserved words, nested ternaries need parentheses and constructors named after the class no longer work.
- PDO defaults to exception mode, so queries that used to fail quietly now throw.

The full list is in PHP's [8.0 backward incompatible changes](https://www.php.net/manual/en/migration80.incompatible.php).

### 8.0 to 8.1, 8.2 and 8.3: notices that pile up

- 8.1: passing «null» to non-nullable parameters of built-in functions is deprecated («strlen(null)», «str_contains($x, null)»). In older code it shows up thousands of times. «strftime()», «FILTER_SANITIZE_STRING» and the «mhash» functions are deprecated too, per the [8.1 list](https://www.php.net/manual/en/migration81.deprecated.php).
- 8.2: dynamic properties are deprecated unless the class uses «#[\AllowDynamicProperties]». So are «utf8_encode()», «utf8_decode()» and «${var}» string interpolation, per the [8.2 list](https://www.php.net/manual/en/migration82.deprecated.php).
- 8.3: targeted changes such as a stricter «range()» and «number_format()» with negative decimals, in the [8.3 guide](https://www.php.net/manual/en/migration83.incompatible.php).

### 8.3 to 8.4: extensions and types

- The IMAP, OCI8, PDO_OCI and PSpell extensions were removed from the PHP distribution and now install from PECL. If your system reads mail over IMAP or talks to Oracle, check this first, per the [removed extensions note](https://www.php.net/manual/en/migration84.removed-extensions.php).
- Parameters with a «null» default but no explicit nullable type («function f(Type $a = null)») are deprecated. The fix is «?Type $a = null».
- «trigger_error()» with «E_USER_ERROR» and the «E_STRICT» constant are deprecated, and «exit()» now behaves like a function.
- OPcache JIT is off by default and several functions throw «ValueError» where they used to warn. Details on the 8.4 [changes](https://www.php.net/manual/en/migration84.incompatible.php) and [deprecations](https://www.php.net/manual/en/migration84.deprecated.php) pages.

## How do you upgrade PHP step by step without breaking production?

The rule is simple: never switch the PHP version directly in production. Prepare it on a copy, test it, roll it out in stages and always keep a way back. This is how we run it:

1. Inventory. List every server, container and hosting account running PHP, with the actual PHP-FPM or Apache module version (it can differ from «php -v»). Include scheduled jobs and cron scripts that call a different binary.
2. Dependencies. Use Composer to find packages that don't accept PHP 8.4 and which ones have a newer release that does. The framework sets the pace: Laravel 10 supports PHP 8.1 to 8.3 and Laravel 11 goes up to 8.4, per its [support policy](https://laravel.com/docs/12.x/releases). Sometimes the framework has to move before PHP does.
3. Extensions. Compare «php -m» on the current server with what the new install ships. The usual gaps: IMAP, OCI8, ionCube or hand-compiled extensions.
4. Code analysis. Static analysis tools find removed functions and compatibility issues without running the system. They don't replace testing, but they tell you where to look first.
5. Staging. A copy of production running PHP 8.4, the same database (anonymized if it holds personal data) and error logging at «E_ALL». Run the automated tests there plus a manual pass through the flows that make money: login, invoicing, payments, reports.
6. Staged rollout. Install PHP 8.4 alongside the current version (many distributions allow several PHP-FPM versions side by side) and move one site or a slice of traffic first. Watch errors and response times for a day before continuing.
7. Rollback plan. Going back should mean pointing nginx or Apache at the old PHP-FPM socket and reloading, not reinstalling. If the upgrade touched the database, keep a tested backup from before the change.
8. Restart and verify. Restart PHP-FPM or Apache so the new version and config take effect, and confirm from the outside which version answers. Keep evidence: version before, version after, tests that passed.

```
php -v && php -m                       # CLI version and extensions
composer check-platform-reqs           # do dependencies accept the installed PHP version?
composer why-not php 8.4.0             # which package blocks PHP 8.4
composer outdated --direct             # direct dependencies with newer releases
composer audit                         # dependencies with known security advisories
sudo systemctl restart php8.4-fpm      # restart the new pool
sudo nginx -t && sudo systemctl reload nginx
```

> **The most common mistake** Bumping PHP from the hosting control panel on a Friday afternoon with no staging copy. The site loads, but a report or a billing integration fails days later because a removed function is only used there. That's why the manual pass through critical flows happens before production changes, not after.

## What if you can't make the December 31 deadline?

A mid-sized system with good tests can move in a few weeks. One with no tests, ten-year-old code and abandoned dependencies takes longer. If you know you won't make it, don't sit still: there are steps that lower the risk while you finish.

- Get onto the latest patch release of your current branch first. On 8.2, that means having the final fixes before support ends.
- Use your distribution's packages or an extended-support vendor, which keep shipping fixes for older branches for a while.
- Shrink the exposure: a firewall or WAF in front, the admin panel behind a VPN, no public «phpinfo()» and the PHP version hidden from response headers.
- Track new flaws in your version. We publish the relevant ones in [this week's alerts](https://security.wits.mx/en/alerts/).
- Migrate in pieces: if you run several systems, start with the internet-facing ones.

If your system is built on Laravel, also read [what happens with Laravel 11 now that it gets no patches](https://security.wits.mx/en/guides/laravel-11-security-patches/). And if you run WordPress sites, the host's PHP version matters just as much: a [hacked WordPress site](https://security.wits.mx/en/guides/wordpress-hacked/) often starts with an old server.

> **Want help with the upgrade?** Security OS takes the inventory of where PHP runs and on which version, reviews Composer and extensions, prepares a staged upgrade with its rollback plan and delivers before-and-after evidence for every change. If there's no time to upgrade yet, we apply your branch's patch or backport in the meantime. Nothing changes in production without your approval. To see where you stand today, start with the [free PHP check](https://security.wits.mx/en/php-check/).

Tell us what system you run, which PHP version it's on and where it's hosted. We'll reply with next steps. [Plan my PHP 8.4 upgrade](https://security.wits.mx/en/guides/upgrade-php-8-4/#contacto)

## Frequently asked questions

**How do I check which PHP version I'm running?**

On the server, with «php -v» in a terminal or «phpinfo()» on a temporary page you delete afterwards. Also check the PHP-FPM or Apache module version, which can differ. On shared hosting, it's in the control panel.

**Is PHP 7.4 still safe to run?**

No. PHP 7.4 stopped receiving security fixes on November 28, 2022. Flaws found since then have no official fix, as happened with PHP2Shell in October 2026.

**When does PHP 8.2 support end?**

On December 31, 2026. After that date PHP 8.2 gets no more security fixes. PHP 8.1 ended on December 31, 2025.

**Can I jump straight from PHP 7.4 to 8.4?**

Yes, you don't need to install each version in between. You do need to review the changes in each one (8.0, 8.1, 8.2, 8.3 and 8.4), because the code has to satisfy all of them. Most problems show up in the 7.4 to 8.0 jump.

**Will upgrading PHP break my site?**

It can, if the code uses removed functions or relies on behavior that changed. That's why you test on a copy first, roll out in stages and keep a rollback that takes minutes.

**Do I need to upgrade Laravel or my libraries before PHP?**

Often, yes. Each framework version supports a PHP range: Laravel 10 tops out at PHP 8.3 and Laravel 11 at 8.4. Run «composer why-not php 8.4.0» to see which package is holding you back.

**Do I have to restart PHP-FPM after upgrading?**

Yes. Workers that are already running keep the old version and configuration until you restart PHP-FPM or Apache.

## Sources

- [PHP: Supported Versions](https://www.php.net/supported-versions.php)
- [PHP: Unsupported Branches (end of life)](https://www.php.net/eol.php)
- [PHP Manual: Migrating from PHP 7.4.x to PHP 8.0.x — cambios incompatibles](https://www.php.net/manual/en/migration80.incompatible.php)
- [PHP Manual: Migrating from PHP 8.0.x to PHP 8.1.x — funciones obsoletas](https://www.php.net/manual/en/migration81.deprecated.php)
- [PHP Manual: Migrating from PHP 8.1.x to PHP 8.2.x — funciones obsoletas](https://www.php.net/manual/en/migration82.deprecated.php)
- [PHP Manual: Migrating from PHP 8.2.x to PHP 8.3.x — cambios incompatibles](https://www.php.net/manual/en/migration83.incompatible.php)
- [PHP Manual: Migrating from PHP 8.3.x to PHP 8.4.x — cambios incompatibles](https://www.php.net/manual/en/migration84.incompatible.php)
- [PHP Manual: Migrating from PHP 8.3.x to PHP 8.4.x — funciones obsoletas](https://www.php.net/manual/en/migration84.deprecated.php)
- [PHP Manual: Migrating from PHP 8.3.x to PHP 8.4.x — extensiones retiradas](https://www.php.net/manual/en/migration84.removed-extensions.php)
- [Laravel: support policy by version](https://laravel.com/docs/12.x/releases)
