As a marketer or website owner, ensuring the safety, security, and optimal performance of your website is critical. Keeping your software up-to-date is an essential step in achieving your objectives. To take advantage of the latest features and performance improvements on your Drupal website, upgrading to PHP version 8.1 is a crucial step. PHP 8.1 offers significant advancements in speed, security, and functionality compared to its predecessor. The enhanced performance of PHP 8.1 can also lead to faster loading times and a more efficient user experience. Our blog will guide you through the steps required to upgrade your PHP installation to version 8.1.
It's important to note that PHP 7.4 is no longer receiving security updates, and Drupal 9.4.x is slated to stop receiving security updates by the end of May 2023. This means that it's a critical time to update your Drupal project to 9.5.x and PHP 8.1 to ensure the safety and security of your system.
In this blog post, I’ll be sharing my experience, steps and timelines for upgrading a Drupal Project to php 8.1.
Disclaimer: All the steps assume that your Drupal project is a composer based project.
Let’s Get Technical - Step by Step Process for PHP 8.1 Upgrades
Analyze Codebase
PHP Code Sniffer with PHPCompatibility standard will be used for analyzing codebase for compatibility with PHP 8.1.
PHP_CodeSniffer is a library that tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.
- Install PHP Code Sniffer
- Install PHPCompatibility coding standard with help of PHP_CodeSniffer Standards Composer Installer Plugin
- Confirm that phpcs is installed correctly, and has PHPCompatibility standard by running `phpcs -i`. It should show output like below
The installed coding standards are MySource, PEAR, PSR1, PSR2, PSR12, Squiz, Zend, AcquiaDrupalStrict, AcquiaDrupalTransitional, AcquiaPHP, Drupal, DrupalPractice, PHPCompatibility, VariableAnalysis and SlevomatCodingStandard
- Generate compatibility report.
- I’d advise to run reports separately for every section of your Drupal code for e.g.
- Run for Drupal Core
- Run for Contributed Modules & Themes
- Run for Custom Modules & Themes
- Run for Vendor directory
- I’d advise to run reports separately for every section of your Drupal code for e.g.
Fix Deprecations
To fix deprecations it is important to understand the changes in PHP 8.1
Exciting new features in PHP 8.1
- Union Types: This feature allows you to specify multiple types for a single variable. For example, you can now write "string|int $x" instead of "mixed $x", which makes your code more readable and less prone to errors.
- Named Arguments: This feature allows you to pass arguments to a function by name rather than by position. This can make your code more readable and easier to understand, especially when you're working with functions that have a large number of arguments.
- Match Expressions: This feature provides a more concise way of handling multiple conditions in your code. Instead of using a series of "if-else" statements, you can now use the "match" expression to check the value of a variable and execute different code based on the result.
- Improved Type Inference: PHP 8.1 introduces several improvements to the way the language infers types. This can lead to more accurate type checking and better performance.
Most notable changes in PHP 8.1
- Nested ternary operators without explicit parentheses
- parent keyword without parent class
- Using array_key_exists() on objects
- Mandatory parameters after optional parameters are discontinued
- Non-existent variables and indexes
Refer below links for more detailed changes
- https://www.php.net/manual/en/migration74.deprecated.php
- https://www.php.net/manual/en/migration80.deprecated.php
- https://www.php.net/manual/en/migration81.deprecated.php
Deprecations in PHP 8.1
- `create_function` function is deprecated, and it is recommended to use anonymous functions instead.
- `assert()` function with string argument is deprecated, and it is recommended to use `assert()` with a boolean expression instead.
- `mb_ereg_replace()` function is deprecated, and it is recommended to use the `preg_replace()` function with the u flag instead.
- `$this` variable is no longer allowed in closure used with `bind()` function
- `ReflectionParameter::getClass()` is deprecated and the recommended alternative is `ReflectionType::getClass()`
- `ReflectionType::__toString()` is deprecated and the recommended alternative is `ReflectionType::getName()`
- `ReflectionZendExtension::__construct()` is deprecated and the recommended alternative is `ReflectionExtension::__construct()`
It's important to note that any code that uses these deprecated features will continue to work in PHP 8.1, but it's recommended to update your code to use the recommended alternatives to avoid compatibility issues in future versions of PHP.
Steps to Fix Deprecations
- Update Drupal core to latest 9.5.x version
- Update Contributed modules to latest version
- If latest version is not php 8.1 compatible, check in issue queue for a patch
- If patch is not found, create a new issue and supply the patch
- Manually fix deprecations in custom code by looking at investigation report
Test Updates
To test the updates, upgrade your local environment to PHP 8.1. Update php_version in Ddev config.yml. Visual regression tool like backstop can be used as a first pass.
Re-analyze Codebase
Once all the fixes are made, it is very important to re-analyze the codebase to make sure everything has been updated. Repeat the process in the "Analyze Codebase" step above and create a final report. Compare both reports and determine if any action is needed.
Prepare for Deployment
Once you are sure, prepare for deployment. Here is a quick checklist for deployment
- Take database backups of production
- Move the site into maintenance mode
- Change the php version to 8.1
- Deploy the code
- Run database updates and configuration import
- Clear Cache
- Turn off the maintenance mode
Congratulations, your site is up and running for PHP 8.1.
Timelines
Timelines to upgrade a Drupal project to 8.1 depends on following factors
- Complexity
- Number of Modules
- Current State for e.g. current state of codebase, how frequently core and contributed modules were updated
Time ∝ Complexity
Timelines are directly proportional to complexity of your build. More complex the code is, it will take more time to upgrade to PHP 8.1
Complexity ∝ Number of Modules
Complexity is directly proportional to the number of modules, themes your project has. High number of modules will increase complexity, and in turn timeline will increase.
Time ∝ 1 / Current State
Timelines are inversely proportional to the current state of the codebase. If you have been maintaining the codebase continuously i.e. keeping core, contributed modules and themes up-to-date with latest updates, upgrading to php 8.1 is going to be a quick and smooth transition.
Below table will give an Idea of estimated time required for upgrading a project to 8.1
Size of the Site | Status | Estimated Time |
~50 Contributed Modules, ~15 custom modules, ~2 contrib and custom themes | Drupal core is in 9.4.x, 50% of the modules are up to date | 3 days - 1 week |
~50 Contributed Modules, ~15 custom modules, ~2 contrib and custom themes | Drupal core is in ~9.1.x, 10% of the modules are up to date | 1.5 week - 2 week |
Depending on the above factor a PHP 8.1 upgrade can take anytime between 3 days to 2 weeks.
At Digital Polygon, we understand that upgrading your PHP and Drupal installation can be a complex process. We are here to help. Our team of experts can guide you through every step of the process, from assessing your system's needs to performing the upgrade itself. Contact us today to learn more about how we can help with your PHP and Drupal upgrade needs.