November 14, 2022

PHP 8 Drupal Compatibility testing

Preparing Drupal code for PHP 8.x

PHP 7.x reaches end of life at the end of November 2022 so on a number of Drupal projects I've had to start preparing for PHP 8.x. With DevOps developers handling the actual server upgrades my job is/was to make sure the Drupal code especially any custom code was compatible from PHP 8.x. Here's how I did it!

All the projects I've been working with are well maintained Composer based Drupal projects which definitely makes the setup a bit easier!


Installing PHPCompatibility

To do the actual compatibility testing I'm going to be using the PHPCompatibility bundle and as I mentioned because I'm using Composer it's pretty straightforward to install. There are probably other ways to audit your Drupal projects PHP compatibility but I liked how easy PHPCompatibility fits into a Composer based projects so decided to test it out.

Here's how to install PHPCompatibility in your Drupal Composer projects:

1) Go to your project root directory (where composer.json is)

2) Run composer require phpcompatibility/php-compatibility --dev or ddev composer require phpcompatibility/php-compatibility --dev if you're using DDEV for your local Drupal development

3) Now we need to set some PHPCompatibility settings so it knows where it's installed. For that we'll use "scripts" part of our composer.json file. Under "post-install-cmd" & "post-update-cmd" add: "\"vendor/bin/phpcs\" --config-set installed_paths vendor/phpcompatibility/php-compatibility"

    "scripts": {
        "post-install-cmd": [
            "\"vendor/bin/phpcs\" --config-set installed_paths vendor/phpcompatibility/php-compatibility"
        ],
        "post-update-cmd": [
            "\"vendor/bin/phpcs\" --config-set installed_paths vendor/phpcompatibility/php-compatibility"
        ]        
    },

4) Next from command line run composer install (the official PHPCompatibility documentation says it should be composer update --lock but for me I got a load of errors).

PHPCompatibility should now be installed within the project as a vendor.

If you're not using Composer you'll need to install PHPCompatibility via git instead.


Run PHPCompatibility on your Drupal project

The PHPCompatibility binary should now be present in /vendor/bin/phpcs, to double check you can run vendor/bin/phpcs --help and you should see the help text like in the screenshot below:

If you don't get the help text then check the output from step #2 above, you may have got an error without noticing.

So assuming all is well with PHPCompatibility you can now start to audit your Drupal project & check it's PHP 8.x compatibility. My projects were running Drupal core 9.4.8 with all contrib modules running on their latest version so I decided to skip auditing core & contrib modules (for now) and focus just on custom modules & themes to start with.

Here's the command to audit your PHP 8.0 compatibility:

vendor/bin/phpcs -p SOURCE_CODE_LOCATION --standard=PHPCompatibility --runtime-set testVersion PHP_VERSION--extensions=FILE-EXTENSIONS-TO-CHECK --report-file=REPORT-FILENAME

SOURCE_CORE = the location of the source code to run the audit on Examples: . for the current directory/whole projects, ./web/modules/custom for custom modules or ./web/themes/custom for custom themes

PHP_VERSION = The PHP version you want to check your projects compatibility against ie. 8.0

FILE-EXTENSIONS-TO-CHECK = The types of files your audit should check, any file that contains PHP basically. For modules this might be php,module,install,inc & for themes php,install,inc,theme

REPORT-FILENAME = The location & name of the file to output the results of the audit to. ie. ./themes-php8.0-test.txt or ./audits/modules-php8.0-test.txt

And the real life commands I used to check my custom modules & themes were:

Modules: vendor/bin/phpcs -p ./web/modules/custom --standard=PHPCompatibility --runtime-set testVersion 8.0 --extensions=php,module,install,inc --report-file=./audits/modules-php8-compatibility.txt

Themes: vendor/bin/phpcs -p ./web/themes/custom --standard=PHPCompatibility --runtime-set testVersion 8.0 --extensions=php,install,inc,theme --report-file=./audits/themes-php8-compatibility.txt

The results being 2 audit .txt files in my sites /audits directory telling me about all errors & warnings related to PHP 8.0 compatibility. From there you can work your way through & fix any issues and then run the audits again.

For me, all projects were already running Drupal 9.4.8 and PHP 7.4 so I actually got very few warnings but it was reassuring to know that the code was going to run on PHP 8 without issue.


Don't forget to test for real!!

The last part of any compatibility testing is actually testing in real life ie. Fire up the website on the PHP version you will be running & use/test the site.

Fortunately, as I now use DDEV for all my local Drupal development this was simply a case of changing 1 line in /.ddev/config.yaml from php_version: "7.4" to php_version: "8.0" and then running ddev start to restart the container :)

From there I checked the Status page at /admin/reports/status and then browsed the sites key pages and then reviewed the database logs at /admin/reports/dblog. If things looked good I could then flag the site as ready for further testing knowing that the PHP 8 compatibility was in good shape!

And that's it for this quick but hopefully useful post on PHP 8 Drupal Compatibility testing, thanks for reading!!