Background
The PHP version on our servers is outdated every 2-3 years.
Consequently, it is necessary to update our PHP version because of security reason.
Every PHP upgrade will take a lot of effort to migrate.
This article is about how we reduce the effort to do that.
A. Where should we look at?
1. PHP Migration guide on Official site
2. PHP version support in external libs/dependencies
Official websites or Github repos of those libs/dependencies
If the libs are installed via composer, you can check via some websites like packagist.org
B. How to migrate existing source code
In the official PHP Migration guide, there are 3 parts to notice to keep the existing source code running on new PHP without problem:
+ Backward Incompatible Changes
+ Deprecated Features
+ Other Changes
1. Backward Incompatible Changes
a) Removed functions
+ Use php-compatibility to detect
composer require --dev phpcompatibility/php-compatibility
php vendor/bin/phpcs --config-set installed_paths vendor/phpcompatibility/php-compatibility/PHPCompatibility
php vendor/bin/phpcs --standard=PHPCompatibility file.php
+ IDEs nowadays can show warnings about undefined functions, so all the functions which no longer exist will be marked as well.
At a higher level, some features in IDEs like `Inspect code` feature of PHPStorm are very useful for helping to detect these issues.
b) Behavior changes
+ Parameters’ acceptable types, functions’ return types must be considered carefully.
+ Use the feature “Find” of IDEs or Editors to go to all the places to make sure the parameters or returned values have the correct type.
For example:
Passing NULL needle to strpos(), strrpos() returns 0 on PHP 7.x but throws an error on PHP 8.x
If your functions and variables have clear typedef in the comments or PHPDoc, it will be easier to track the value type.
If the typedef and PHPDoc are not clear enough, it’s safer to set a default value like null coalescing operator (??) before passing parameters into functions.
For example:
strpos($mystring ?? ‘’, $findme)
count($array ?? [])
2. Deprecated Features
Combine with PHPStan or Psalm
+ PHPStan
composer require --dev phpstan/phpstan
Create a phpstan.neon configuration file:
parameters:
level: max
paths:
- src
deprecationRulesInstalled: true
vendor/bin/phpstan analyse
+ Psalm:
composer require --dev vimeo/psalm
vendor/bin/psalm --init
vendor/bin/psalm
Use IDEs to find the deprecated functions, like “Inspect Code” of PHPStorm or PHP Intelephense, PHPStan and Psalm Extensions on VS Code.
It’s not always required to fix the deprecated features, but if your project plans to run a full test for the whole system, it’s worth replacing those features so that you don’t have to fix them and test again when they are completely removed in the future
3. Other Changes:
a) Error reporting level change
This can be easily missed, because the parameters and return type are not changed.
Actually, it’s very important.
For example:
unserialize() error reporting level is changed from E_NOTICE to E_WARNING.
Even though it’s not E_ERROR level, PHP will still throw errors if your PHP error reporting level in PHP config is set to E_WARNING or your project is in strict mode.
b) Data type affects comparison result
Be careful with your equality ( == ) operator.
If your source doesn’t strictly follow that, you can set a rule inside the phpcs setting to enforce using Strict equality (===).
Then run PHPCS to find all the places which need to be reviewed again
C. A website worth following
A website which summarizes the changes in new PHP versions and suggests how to replace removed/functions by equivalent functions
Come work with us!
Commerce & Marketing Company Leisure Product Department (LPD) is seeking talented individuals to join our team in developing new services, managing daily operations, and driving continuous improvements. Recruitment is open for a variety of positions, including engineers and product managers. We look forward to receiving your application!