Testing PHP 8.1 Updates

Tis the season for PHP updates!

With Drupal 10 coming in the not so distant future (Beta comes out in just a few weeks), I’m starting to do some testing of PHP 8.1 on sites that are currently running PHP 8.0 and running Drupal 9. It’s been a mixed bag, and I wanted to share some of the experiences with you just so you can adequately plan for your own update processes.

In this article we’ll have a look at the following:

  • local environments

  • composer

  • modules / plugins / other tools

  • hosting environments

Local Environments

TLDR: Local environments should be ready for PHP 8.1.

Running PHP 8.1 locally is super easy if you’re running Homebrew and Docker solutions like Lando or DDev.

Strictly speaking, you don’t have to update the php on your host machine if you’re running everything in containers, but I find it to be a little easier to do so just in case I decide to run a composer command outside the container.

Updating Host Machines

As always wit homebrew, this can be accomplished with 2-3 simple commands:

brew unlink php@8.0 (or whatever version you're running)
brew link php@8.1 

You might also have to install php 8.1 before you can link it:

brew install php@8.1 (but you'll only have to do this once)

Note: if you have customized your php.ini file for older versions of PHP, you’ll have to do so again once you’ve updated to PHP 8.1 as well. You can find the php.ini file for php 8.1 by running the following command:

php --ini

For me, I see something like this:

Configuration File (php.ini) Path: /opt/homebrew/etc/php/8.1 Loaded Configuration File:         /opt/homebrew/etc/php/8.1/php.ini Scan for additional .ini files in: /opt/homebrew/etc/php/8.1/conf.d Additional .ini files parsed:      /opt/homebrew/etc/php/8.1/conf.d/ext-opcache.ini

And in this case, I’d want to edit the first one.

Updating Containers

In terms of updating things like Lando or DDev this usually winds up being a single line of code that needs to change. If you look at a Lando example (e.g. https://github.com/mikemadison13/blt-lando/blob/main/.lando.yml#L6) you would just replace

config:   webroot: docroot   xdebug: false   php: '8.0'

with

config:   webroot: docroot   xdebug: false   php: '8.1'

Then, you’d need to rebuild the containers for the update to take effect. This can be done by running “lando rebuild” (you shouldn’t have to destroy the containers for this update).

Be warned, that sometimes if you are managing php via composer then you may get some php platform errors at this point. But, onward to composer (and we’ll fix those).

Finally, don’t forget to update any additional containers for CI/CD used by your team!

Composer PHP Version

TLDR: composer is ready for PHP 8.1 (but not all dependencies are, see below)

Updating composer to expect / support PHP 8.1 is super simple. Once you’ve updated the above, you can simply edit your composer.json file and run a composer update command.

There are upwards of two entries in a composer.json to look at:

The first, and most common, is the require section of the composer.json file and is a dependency on php itself. See https://github.com/Drupal4Gov/Drupal-GovCon-2017/blob/develop/composer.json#L89. Not all projects have this today, but I’d advise adding it.

The other is in the config section of composer.json for platform php, see https://github.com/acquia/blt/blob/main/composer.json#L58. This one is really useful to “force” composer to stay on a particular php version. Sometimes if you have multiple people working on a project and they are all using different setups (not advised) you can inadvertently downgrade PHP version. I usually don’t bother with this, but some do!

Once the composer.json is updated, just run:

composer update php --with-all-dependencies

Modules / Plugins / Tools

TLDR: here’s where things get interesting…

My experience with php version changes is sort of like a box of chocolates… you never know what you’re going to get. Ironically, upgrading from PHP 7.4 to 8.0 was a very painless activity for me. However, upgrading from 8.0 to 8.1 has been incredibly painful. Why? Symfony.

Upgrading from 7.4 to 8.0 didn’t end up forcing major version changes of symfony. The result is that many tools like BLT, Behat, etc. were able to continue on with the same versions of things, no problem. HOWEVER in the PHP 8.1 arena this now requires you to upgrade to Symfony 6.x which has some significant changes in structure, dependencies, etc. vs Symfony 3 and 4.

Thankfully, most Drupal modules don’t have dependencies on Symfony itself (more on this in a moment) but many plugins do. So… the sad news is that many key dependencies for tools (like Behat) simply aren’t ready for PHP 8.1 yet. Which means if you want to be an early adopter of Drupal 10 you may have to stop using some tools (like Behat) in the short term.

This doesn’t mean that all Drupal modules are ready to go. Many Drupal module maintainers tend to wait until the Drupal 10 beta drops to get their modules compatible. Granted, PHP 8.1 and Drupal 10 aren’t “directly” linked (a module can be PHP 8.1 compatible without being Drupal 10 compatible) but it’s a good rule of thumb that these are tightly linked. As always with modules, have a look at the module’s page to see if it has had recent releases and check out the composer.json in the module’s repo to see what versions of PHP are there. The very good news is that the vast majority of modules that are compatible with Drupal 9 only need a info file change to be compatible with Drupal 10, see https://dev.acquia.com/drupal10/deprecation_status/projects.

It’s unfortunate that Behat isn’t ready yet given that automated testing is one of the fastest ways to find broken portions of a website. So, you may want to consider changing your testing suite over to phpunit or nightwatch (both of which are ready to go). I’m currently tracking the Behat issue here: https://github.com/jhedstrom/drupalextension/issues/614 (note this isn’t Behat itself, it’s one of the Drupal-specific plugins).

For what its worth, that Symfony 6.x update can be very very challenging for maintainers to get ready for. It took us months and multiple pull requests on BLT to get ready for it (because I ended up having to refactor almost all of our command execution from strings to arrays to be compatible with the Symfony 6 execution logic). It’s a pain in the ass, and I so appreciate the work being done in the community to address this update. Just remember folks need time to address this, and hopefully as we get closer to D10’s release we will see more and more work happening!

Hosting Environments

TLDR: Your miles may (and will) vary

Hosting PHP 8.1 is something you “probably” aren’t ready to do yet given all of the above. BUT if you do feel confident that your project is ready for the jump, definitely make sure that your hosting environment support it. Acquia has some PHP 8.1 support (but not all products are ready at the time of writing). Pantheon says they do technically support it but it isn’t recommended yet. And so on. Definitely make sure that you know for sure if your hosting provider is ready for PHP 8.1 before you deploy any code!

In Conclusion

I find it super irritating that a major php version update (7.4 to 8.0) was actually easier than a minor one (8.0 to 8.1) but that’s how the game works, I guess. This is why it’s always so important to test well ahead of any big upgrade. Sometimes it’s no big deal. Sometimes it is. But the important thing is to make sure you identify problems before you deploy anything anywhere (because PHP fatal errors have a habit of disrupting… everything). Good luck and happy testing!

Related Content