Ahosting Logo
Knowledge Base

How to Upgrade the PHP Version of a WordPress Site

Moving PHP version without discovering the problems in publicCheck what is installedplugin and themecompatibility, beforeanythingTest on a staging copysame version, sameplugins, real contentFix or replace what breaksusually one abandonedpluginSwitch the live siteand watch the error logfor a dayStaying on an old PHP version is a security decision made by inaction, since unsupported versions stop receiving fixesentirely.

Sites sit on old PHP versions for years because nobody wants to be the person who broke the site. The risk of moving is real, small, and entirely measurable in advance. The risk of not moving is a version that receives no security fixes.

Find out what is actually running

WordPress reports it under Tools, Site Health. From the command line:

php -v
wp --info

Be aware these can disagree with the panel. The version the panel shows and the version the account actually uses can differ when a PHP selector is involved, and the site's real version is the one that matters. There is more on checking properly in MultiPHP Manager.

Update everything first

This resolves most compatibility problems before you meet them. Current versions of maintained plugins and themes already support current PHP; the incompatibilities that remain are in code nobody has touched for years.

wp core update
wp plugin update --all
wp theme update --all

Take a backup before this, not after. Keeping WordPress updated walks through doing it safely.

Test on a copy

Switch the version on a staging site, not the live one.

Then exercise the parts that do not announce themselves: the checkout, contact and booking forms, the admin screens, image uploads, and anything scheduled. A homepage that loads proves very little. The failures land in code paths that only run occasionally.

Turn on error logging while you do it, so warnings are recorded rather than silently swallowed:

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_DISPLAY', false );
define( 'WP_DEBUG_LOG', true );

Debugging with WP_DEBUG and logs covers reading the result. Expect a lot of deprecation notices; those are noise. Fatal errors are the list you care about.

Setting up a WordPress staging site deals with having somewhere to do this.

What actually breaks

Almost always one abandoned plugin.

The most common causes are calls to functions removed years ago, and code relying on behaviour newer PHP tightened. Neither is fixable by you unless you maintain the plugin.

Which turns the upgrade into a decision you were already going to face: a plugin that no longer runs on supported PHP is a plugin that has been abandoned, and it is also not receiving security fixes. Replacing it is the answer, and the PHP upgrade simply forced the timing. Choosing and vetting plugins sets out picking the replacement.

If several plugins fail at once, use the halving method rather than testing them one by one. There is more in finding which plugin is causing a problem.

Switching, and rolling back

Change the version in the panel. The rollback is the same action in reverse and takes seconds, because nothing about the site's files has changed, only which interpreter runs them.

That makes this one of the few changes where the recovery is genuinely instant. Do it at a quiet hour anyway, and watch the error log for the first few minutes.

Move one version at a time

Going from a very old version to the newest in one step makes any failure hard to attribute.

Stepping through gives you a working state to return to and a much shorter list of suspects at each stage. It takes longer and it is the difference between a fault you can explain and one you cannot.

What you gain

Newer PHP is meaningfully faster on the same hardware, which shows up directly in how long the server takes to begin responding.

And it is supported, which is the real argument. An unsupported version receives no fixes for vulnerabilities that are publicly known. Securing WordPress against vulnerabilities deals with where that sits among the other risks.

Find the incompatible code before switching

Rather than switching and reading errors, the plugins and theme can be checked against a target version first.

A compatibility scanner reports calls to removed functions and constructs a newer version rejects, per file, without running anything. That turns "something will break" into a list.

wp plugin list --field=name --status=active
wp plugin list --format=csv --fields=name,version,update,auto_update > plugins-before.csv

Keep that second file. After the upgrade it is the record of exactly which versions were running when it worked, which matters if a problem appears a week later and the plugin has updated twice since.

The scanner reports far more than genuinely breaks, since a deprecation is not a failure. Treat the fatal-level findings as the list and the rest as background. For separating them once running, see debugging with WP_DEBUG and logs.

Exercise the paths that only run occasionally

Loading pages tests the code that renders pages. The failures land elsewhere.

The paths worth exercising deliberately on the staging copy: a complete checkout, a form submission that sends mail, an image upload, a scheduled task run by hand, and any import or export the site offers.

wp cron event run --due-now
wp eval 'wp_mail("[email protected]","test","body") && print "sent\n";'

Those two cover the largest blind spots: scheduled work and mail, because neither runs during ordinary browsing and both break in ways nobody notices for days.

Watch the first hour after switching

The rollback is instant, which only helps if somebody is looking.

tail -f ~/logs/example.com.error.log | grep -i 'fatal\|error'

Watch the error log for the first few minutes, and check the front page, the admin and one dynamic page. The checkout, the search, whatever the site does.

Errors that appear only under real traffic are the ones staging missed: a path exercised by a particular visitor, an integration called by an external service, a cached page expiring and being rebuilt for the first time on the new version.

Update the things that reference the version

The switch is one setting and several other places may name the old version.

A `.htaccess` handler line pinning a specific PHP version overrides the panel entirely, which produces the confusing state where the setting says one thing and the site runs another.

grep -rn 'ea-php\|AddHandler\|AddType.*php' ~/public_html/.htaccess

Also worth checking: any cron command that calls a versioned binary directly, and any deployment script with the path hard-coded. Both keep using the old version silently. There is more on where the setting actually lives in MultiPHP Manager.