Upgrading a WordPress site, plugin, or theme to a new version of PHP is a task that recurs regularly. But how do you do this as efficiently as possible? How do you know you won’t overlook anything? Is there a roadmap for it?

In this article, we’ll tackle these questions (and more) and look at what’s involved in a smooth transition to supported releases of PHP 8 for your WordPress site, plugin, or theme, including a road map.

We’ll do this based on an interview we conducted with PHP expert Juliette Reinders Folmer. She devotes most of her daily life to programming and everything around it, focusing mainly on open-source projects, including WordPress.

Are you ready to make the switch smoothly too? Curious about our step-by-step plan? Then let’s dive right in!

The status of PHP 8 releases in 2024

There are good reasons to use supported PHP versions. Chief among them is security. In late 2023, PHP 8.0 reached end-of-life and is no longer being updated to fix security vulnerabilities. Version 8.1 will be in the same position by the end of 2024. And yet, releases of PHP 7 continue to top usage statistics for PHP websites.

Website owners currently running PHP 8.0 or earlier should definitely be planning to switch, even if that means moving to the latest version one release at a time. Here’s a collection of migration guides and notes that can help get you on track.

After reading that official documentation, you’ll see what has changed in recent releases of PHP 8 and what you need to do to get your PHP projects running without problems.

If you’re unsure what the best way to start is, no problem. In the conversation with Juliette, we discussed this in detail, and we will explain to you in this article as fully as possible how you can switch to PHP 8.x.

We will also explain in informative boxes how to perform various operations in MyKinsta, our proprietary control panel for all your WordPress sites, applications, and databases.

Switching to PHP 8.x: How to get started

Switching to PHP 8.x sounds simple, and technically, it is. Many hosts allow you to specify which version of PHP you want to use for your website in the admin panel. At Kinsta, switching to a release like PHP 8.3 can be done with a single click in the MyKinsta dashboard.

But before you do, there are some things you need to be sure of. Depending on your level of knowledge and experience, we recommend the following:

  • If you have built your own WordPress site with standard themes and plugins, without having much knowledge of PHP, hire a developer or agency to investigate whether your site is suitable to run on PHP 8.x. Are you looking for a third party that can help you with this? Then look at our Partners page listing several trusted companies that can assist you.
  • If your WordPress site was built by an external party, a developer, or an agency, contact them to ask if your site can run on PHP 8.x.
  • If you have built your WordPress site — with your own custom theme, for example, or self-developed plugins — we have a road map for you below.

If your site falls into one of the first two categories, we certainly invite you to read through the rest of the article, but we don’t recommend you start testing your site for compatibility yourself. Leave it to the professionals.

Whatever you choose, we would advise you not to just switch your live site to a newer release of PHP 8 and “see if it works.” Are you curious about what your site will look like, and you can’t wait to see it running on PHP 8.x? Then start testing within a staging environment. A good host will allow you to easily set up a staging environment.

Screenshot showing the creation of a new site environment in MyKinsta.
Creating a new site environment in MyKinsta.

In the staging environment, you can activate a newer release of PHP 8 and see if this update works well with your site. It is also possible to work with a local copy of your site. With our free DevKinsta development tool, you can easily import your site from the MyKinsta dashboard, after which you can change the PHP version to one currently supported.

If you don’t see any problems in the staging environment, it doesn’t necessarily mean there aren’t actually any problems. The road map below will tell you why.

PHP 8.x compatibility testing: The road map

Testing: the keyword to good software. Even for WordPress websites and their components, such as themes, plugins, and the WordPress core, testing is the means to ensure that things don’t happen that you don’t want to happen.

A software development project consists largely of testing. In this article, we look specifically at the tests that can help you make the transition to PHP 8.x go smoothly. In our article on DevOps Tools, you’ll find a section with a collection of tools you can use.

The following types of tests are discussed in this blog post:

Let’s look more closely at the different types of tests we can perform.

Static analysis (or static testing)

The first step you can take as a PHP developer is to perform a static analysis of your code with various tools. Static analysis is the process of analyzing software without executing the code. With static analysis, it is possible to detect errors, detect problems with PHP 8.x compatibility, enforce coding standards (for example, the WordPress Coding Standards), and even modifying and cleaning up the code is possible.

Tools for static analysis

You can perform a static analysis with various tools, such as:

You should be looking out for deprecated or deleted functions, changed default values of function parameters, whether to use concat without parenthesis, whether to use match as a function name (since it has been reserved since PHP 8.0), etc.

A screenshot showing a view of the access.log in MyKinsta.
Viewing an access.log in MyKinsta.

Unit testing

The next step in the process is unit testing. Unit testing is a method of testing pieces of code individually. In unit testing, specific targeted tests will be developed for each unit. This will involve running through different scenarios. Preferably, each scenario is tested separately from the others so that the tests are independent of one another.

Having unit tests alone, of course, is not enough. They also need to be run. Unit tests are best automated using CI (continuous integration) tooling such as Jenkins, GitHub Actions, or Travis.

An example from GitHub Actions
An example from GitHub Actions

Supporting multiple versions of PHP

As a plugin builder, if you want to support multiple PHP versions, ensure the tests in CI are run against all PHP versions you support.

Of course, you can also support only newer versions, the choice is entirely up to you.

Testing that includes releases of PHP prior to 7.3 might require multiple PHPUnit versions. But once you have the tests running, the next step is to make sure the problems found in the tests are fixed.

Code coverage

Running these tests is the most reliable way to find cross-version incompatibilities.

In doing so, pay attention to the code coverage of your tests:

  • Suppose you have a function A and have written a test for it, and function A call functions B, C, and D as part of the logic in the function.
  • The test for function A is written to test the logic of function A, but it will also call functions B, C, and D during testing. For functions B, C, and D, you then usually only test the “happy path” — the situation where everything goes well — and thus, those functions are also not yet fully tested, although (part of) the code in those functions is executed during the testing of function A.
  • For each of your tests, indicate which code is specifically being tested. You do this by giving each test a @covers. This way, B, C, and D are not “counted” in the code coverage calculation, which allows you to see what part of your code is covered by tests.

Often developers write and test — sometimes even unknowingly — for the “happy path.” In these cases, testing what happens when unexpected data is passed to a function is also necessary. Testing with only expected values/types is not enough.

The second part of the above quote is often forgotten, when it is perhaps even more important than the first part. What happens if you pass an incorrect type? Do you get an error message? Or is the variable cast with the function continuing as normal? What if an unexpected value is passed to the function?

Be sure to test your functions with unexpected variables, types, and values. Only then can you rely on your tests to find problems that a new PHP version may cause.

PHP is getting stricter

PHP is becoming more precise (strict) in how it handles “types” for PHP’s own functions, as well as things like dynamic properties. These changes are generally intended to help developers deliver error-free code (well, code with fewer errors). But this can present quite an upgrade hurdle for pre-existing code written based on the “old” tenets of PHP.

Because of this drive for more helpful error messages in PHP, you can see that making existing code suitable with new PHP versions takes more and more time. Making code that worked on PHP 5.6 suitable for PHP 7.0 only took a fraction of the time in most cases compared to upgrading code to make it suitable for PHP 8.1 and above. And that’s despite the fact that PHP 7.0 was a “major” release, while PHP 8.1, 8.2 and 8.3 are considered “minor” releases.

In many cases, testing is still the only reliable way to determine what needs to be modified to support a new version.

Unit testing is possible with various tools, including:

Many of these tools are built based on, or in conjunction with, PHPUnit.

Ultimately, it doesn’t matter what tools you use. The most important thing is that you test, and get the tests running on new PHP versions.

Integration testing

Integration testing is the next step we will perform, after static analysis and unit testing. An integration test is where real-life situations are tested in a larger context than just a “code unit.” These include testing with an active (test) database or testing with an external API, to give just two examples.

So, when you test the code of a plugin or theme in the context of WordPress and use a real version, these are, by definition, integration tests.

WP Test Utils (again written by Juliette and sponsored by Yoast) is an excellent tool for integration testing. WP Test Utils provides tooling to write integration and unit tests, in which WordPress is “mocked up” using Brainmonkey and Mockery, where commonly used WordPress functions are “faked” so that you are testing your own code and not the WordPress code.

WP Test Utilities on GitHub
WP Test Utilities on GitHub

Integration testing with WordPress is a trickier story because it involves integration with WordPress and WordPress’ test suite. Depending on which versions of WordPress a plugin or theme supports, you have to consider which PHPUnit versions are supported by WordPress itself to run the tests on different PHP versions.

Since WordPress 5.9, PHPUnit version 9 has been used for testing on PHP 7.3 and above.

Want to learn more about how to run integration tests against multiple different versions of WordPress, including WordPress 5.9 and above? Then read about it on WordPress’ website.

Manual testing

Now that you’ve gone through unit testing and integration testing and have fixed all the issues you found, it’s time to do manual testing. Your site is running, and your own code is working, but you’re also using plugins A, B, and C. Do you know if those plugins are compatible?

For example, check this with the plugin’s authors and see if they indicate that it is PHP 8.x compatible. The question then, of course, is how the plugin was tested. Often the answer here is: in isolation. The plugin’s functions have usually been tested in conjunction with WordPress alone, without other active plugins. And even if other plugins were used within these tests, chances are that not all plugins used by you were part of the testing, so take such a compatibility statement with a grain of salt.

For example, a WordPress site with 3 plugins (A, B, and C). It’s possible that plugin B, for example, returns an incorrect variable type via a filter, which plugin C, using the same filter, wants to work with. This can then cause a fatal error because the type is no longer what is expected. Plugin C is then seen as the culprit for the error message, even though plugin B is the real offender.

Plugin interoperability-incompatibilities are impossible to discover when testing in isolation. The more active plugins, the more likely something will go wrong. For example, it would be very beneficial to pass page requests from a live website to a staging environment (with error logging enabled) to discover what is actually going wrong.

With this type of problem, a site owner will usually only see a message that there was an error with the last executed code (in this case, from plugin C), even though plugin C is not necessarily the cause of the problem.

In most cases, a lot of manual, human work is involved, and a healthy amount of elbow grease is required to detect and fix these problems. This could be automated using end-to-end testing, but we don’t see this happening much in WordPress.

Test availability for utilized plugins

For developers and development teams: Accept code only when tests are available. This way, you ensure that less manual testing is required, which saves you a lot of time.

Question its testing strategy if you want to buy a commercial plugin or theme. That way, we collectively create awareness among developers/development teams in the WordPress community to get testing higher on the agenda, and we all benefit.

Testing is often viewed — unfairly — as a cost when, in reality, it saves money. The extra investment required to write tests pays off in the form of significantly fewer bug reports and less time spent fixing bugs. In addition, with automated software testing, extensions and modifications can be done faster because the tests can speedily confirm that existing functionality continues to work.

The Role of WordPress hosts and PHP 8.x

For the average site owner, guidance from your host is highly desirable. Consider the following:

  • Documentation and updates for customers that WordPress Core, plugins, and/or themes are (in some cases) not PHP cross-version compatible
  • Options for testing (such as working with a staging environment)
  • Methods for error reporting and contacting support

This also benefits a web host, as site owners often contact the host for help when problems arise. In the case of a switch to a more recent release of PHP 8.x,  the site owner is responsible for potential problems, and the more information the owner has to properly prepare for the switch, the better.

Making a new release of PHP available to customers as a web host is one thing, but in doing so, they must make sure to create awareness among customers so they’re aware that problems might surface. Testing your site in a staging environment with a different version than live is recommended. (Selecting PHP versions is available by default at Kinsta.)

Minimum PHP version for WordPress

To avoid problems, it’s important that WordPress site owners are aware of and informed on the minimum PHP version that will allow their site to run safely. For their part, site owners can modify the PHP version themselves (possible at Kinsta for all packages) or ask their host to update the site to a newer PHP version. In extreme cases, you can switch to a host that supports these newer versions.

Because WordPress only requires a minimum version of 7.4, there is insufficient motivation for many hosts and website owners to update their sites. And this is despite the fact that PHP 7.4 reached its end-of-life in November 2022.

If WordPress ever does increase the minimum PHP version, this may mean that many sites will no longer be compatible with an update to the latest WordPress version. However, security updates will continue to be released for those outdated versions for quite some time.

Summary

To switch to a supported version of PHP 8 for your website, there are several steps that you, or your developer, must perform. Important steps include:

  • Static analysis
  • Unit testing
  • Integration testing
  • Manual testing

When switching to PHP 8.x, ensure everything has been properly tested. This is the only way to guarantee that your site will run properly, quickly, and securely on a newer PHP version.

We thank Juliette immensely for participating in this article and for all her work on the tools mentioned!

Photo of Juliette, taken by Jip Moors and used with permission.

Marcel Bootsman Kinsta

Business Development Manager Dutch and DACH Markets