PHP · 9 min read · Updated Oct 25, 2026

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

PHP 8.1 no longer gets security fixes and PHP 8.2 loses them on December 31, 2026. How to move a legacy system to PHP 8.4 in stages, with testing, a rollback plan and no production outage.

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 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 and its list of unsupported branches.

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

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.

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.
  • 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.
  • 8.3: targeted changes such as a stricter «range()» and «number_format()» with negative decimals, in the 8.3 guide.

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.
  • 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 and deprecations 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. 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.
Useful commands (adjust service names to your distribution)
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

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.
  • 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. And if you run WordPress sites, the host's PHP version matters just as much: a hacked WordPress site often starts with an old server.

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

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

Written by Samuel Hinojosa and the wITS security team · Updated Oct 25, 2026 · Markdown

Keep reading

All guides

All guides →

Contact

Want us to review your company?

Tell us what you run (cloud, servers, PHP, WordPress) and we'll tell you what we'd review first.

Guadalajara, Jalisco, Mexico

Also on WhatsApp at +52 56 6107 7931, or at ventas@wits.mx.

We only use your data to reply. Privacy notice.