Learn how to upgrade PHP 5.4 Projects to PHP 8.1

In this tutorial, you will understand how to upgrade PHP 5.x projects to latest and stable version of PHP 8.1. This post is highly expected to work for all the PHP projects starting 5.x to the 7.x as well as to the current latest stable version PHP 8.1

Why procrastinate upgrading PHP?
There are might be several small, medium and enterprise level Web Applications that are still running on PHP 5.4. The most not-so-convincing reasons that they are still on out-dated version of PHP could be
- lack of technical expertise to upgrade PHP to a stable version in a methodical way
- lack of understanding of what are all the areas of your legacy code base that your application is spread across
- anticipating something will break after upgrading old PHP to latest stable version.
There could also be many other reasons, but its time for you to move on. We will now understand the impact of not upgrading to the stable version of PHP.
What is the Impact?
Upgrading your outdated PHP code to latest stable version will help you keep safe from potential security vulnerabilities creeping in to your application. According to , A9:2017-Using Components with Known Vulnerabilities, your application is vulnerable If software is vulnerable, unsupported, or out of date. It also states that,
If you do not fix or upgrade the underlying platform, frameworks, and dependencies in a risk-based, timely fashion. This commonly happens in environments when patching is a monthly or quarterly task under change control, which leaves organizations open to many days or months of unnecessary exposure to fixed vulnerabilities.
https://owasp.org/www-project-top-ten/2017/A9_2017-Using_Components_with_Known_Vulnerabilities
Take a leap and move forward and upgrade PHP
To answer all the aforementioned reasons and refrain from further procrastination, this short and sweet guide will help you to upgrade your PHP application to its latest stable version in a step-by-step approach.
Using this proven approach of upgrading outdated PHP to latest PHP 8.x version, you will have the following outcome:
- You will be able to successfully upgrade your PHP 5.x code to stable release of PHP 8.1
- The choice of various PHP coding standards you can choose from to upgrade such as
- MySource,
- PEAR,
- PSR1,
- PSR12,
- PSR2,
- Squiz,
- Zend and
- PHPCompatibility
- Upgrade from choice of code sniffing standards such as:
- phpcompatibility/php-compatibility
- DealerDirect/phpcodesniffer-composer-installer
- higidi/composer-phpcodesniffer-standards-plugin
- squizlabs/php_codesniffer
- The report that help you identify areas to take actions to quickly fix and regress the functionality
- The final report with highly detailed information that includes:
- Warnings occurring at each and every line across all files in the project
- Erroneous syntax that is incompatible with target version of PHP along with line number, possible suggestion/alternative across all the files in the project
Upgrade PHP 5.4 Projects to PHP 8.1
With this pretext, we will proceed our tutorial to understand how to upgrade PHP 5.x project to PHP 8.1 or further future stable versions.
Install Composer
As an initial setup, we will install composer. Installing composer on MacOs or *nix platforms is very straight forward. But if you are following this tutorial from a Windows based OS, here is my approach.
Ensure you have PHP installed and made available as environment variable.
Follow the command-line installation of Composer for Windows OS as specified on official composer website. Do not install Composer-Setup.exe as it never helped me with package management on Windows OS đ . To install composer via CLI (Command Line Interface), run the following commands from the terminal.
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" php -r "if (hash_file('sha384', 'composer-setup.php') === '906a84df04cea2aa72f40b5f787e49f22d4c2f19492ac310e8cba5b96ac8b64115ac402c8cd292b8a03482574915d1a8') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" php composer-setup.php php -r "unlink('composer-setup.php');"
Update composer.json
You will find a composer.json file in the project if your PHP project manages third party PHP packages used by your application. Update the composer.json
file such that the require-dev
 section looks like this. If there is already a require-dev
section, add just the line "phpcompatibility/php-compatibility": "*"
to the list.
"require-dev": { "phpcompatibility/php-compatibility": "*" }, "prefer-stable" : true
Now we will add post-install-cmd
and post-update-cmd
command to the scripts
section of composer.json
as follows:
"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" }
The composer.json
file at this point of time will look something like below.
{ "config": { "platform": {"php": "5.4"} }, "require-dev": { "phpcompatibility/php-compatibility": "*", "DealerDirect/phpcodesniffer-composer-installer":"^0.6.0" }, "require": { "twig/twig": "1.26.*" }, "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" } }
Note that the rest of the packages in require are omitted for brevity. Also, you can notice that the require-dev
also has an additional code sniffer "DealerDirect/phpcodesniffer-composer-installer":"^0.6.0"
. This means that if you are using more than one external PHP CodeSniffer standard, you can specify any of the following code sniffers listed below.
- DealerDirect/phpcodesniffer-composer-installer:â^0.6.0âł
- âhigidi/composer-phpcodesniffer-standards-pluginâ: â^1.0â
- âsquizlabs/php_codesnifferâ: â3.*â
Setup Composer to be accessible from CLI
If you are on *nix or MacOS, after installation of Composer, you are able to access composer from cli as per the official docs. But if you are Windows OS, then from the Command terminal, navigate to the project which you want to upgrade PHP to latest stable PHP. Run the following command:
echo @php "%~dp0composer.phar" %*>composer.bat
The preceding command will create a batch file named composer.bat
with the contents @php "%~dp0composer.phar"
inside it.
Run the following command to install PHP compatibility and PHP code sniffer
composer update --lock
Run the following command to check phpcs
is installed
vendor\bin\phpcs.bat
Output:
The installed coding standards are MySource, PEAR, PSR1, PSR12, PSR2, Squiz, Zend and PHPCompatibility
Run Upgrade Analysis
Run the any one of the following commands to perform compatibility check of all the PHP files in your project to be compatible with PHP 8.1.
vendor\bin\phpcs.bat -p . --standard=PHPCompatibility --runtime-set testVersion 8.1 --extensions=php --report-full=phpcs.txt
vendor\bin\phpcs.bat -p . --standard=PHPCompatibility --runtime-set testVersion 8.1 --extensions=php --ignore=*/vendor/* --report-full=phpcs.txt
Explanation of various attributes
-p
: Indicates the path where to check the compatibility standard. A dot (.) indicates to check the current directory and all the sub directories recursively--standard
: Accepts one of the coding standard followed. The common value is one of the available options- MySource
- PEAR
- PSR1
- PSR12
- PSR2
- Squiz
- Zend
- PHPCompatibility
--runtime-set
: Accepts testVersion with the target version we want to test our code compatibility with. In our case we want to test our PHP 5.4 code base and test our code base is compatible when we upgrade our runtime to version PHP 8.1.--extensions
: Accepts any file extensions that we want to target for thephpcs
routine to test the testVersion compatibility. If you have custom template files with file extension other thanphp
but the are filled with PHP code, then ignore this argument.--ignore
: Accepts the directory path to ignore. Typically you may not need vendor directory as you donât want to touch the code base of third party referenced libraries.--report-full
: Accepts text file name to which all the resultant code upgrade analysis is dumped to.
Patience and CPU
The phpcs
is a CPU intensive operation. It scans each and every line of your repository. When this report is generated on project that has .php 4434 File(s) (included the files in vendor directory but excluded them for compatibility check) the operation took approximately above 65 mins on a PC with 16 GB RAM, i7 processor with 4 CPU cores. So to speed up memory based operation it is recommended to leave the PC and donât do any multi tasking.
Understanding Report
The report will have the file entry only if the phpcs
has identified a potential warning or error identified at a particular line number in the php file along with detail. This line level detail has instructions or suggestions on what need to be done to make it compatible with the PHP runtime we are targeting to upgrade our code base to. Other files which pass or succeed through the phpcs
scan wonât be added in the report. This means that the files which are not in the report already meet the code compatibility with target version of PHP we are planning to upgrade to.
Example of Warning from Report
The following snippet of text gives an idea of how a sample would look like in case of warning found in a particular php file.
FILE: E:\my-web-site\index.php ---------------------------------------------------------------------- FOUND 0 ERRORS AND 1 WARNING AFFECTING 1 LINE ---------------------------------------------------------------------- 22 | WARNING | The "result" parameter for function parse_str() is | | missing. Passing this parameter is no longer | | optional. The optional nature of the parameter is | | deprecated since PHP7.2 ----------------------------------------------------------------------
Example of Error identified from Report
The following snippet of text gives an idea of how a sample would look like in case of error found in a particular php file.
FILE: E:\my-web-site\util\common.php ---------------------------------------------------------------------- FOUND 1 ERROR AFFECTING 1 LINE ---------------------------------------------------------------------- 245 | ERROR | Using 'break' outside of a loop or switch structure is | | invalid and will throw a fatal error since PHP 7.0 ----------------------------------------------------------------------
We see that the error message is so intuitive. Based on such information, we move toward fixing those syntax to be compatible with target version we are trying to comply with.
Conclusion
Once you are done with all the fixes, you can plan action items to regress in the workflows and functionalities. Thus you will now have a vulnerability free, up-to-date version of PHP that is both latest and stable.
If you found this tutorial helpful, please do bookmark it đ (Ctrl +D) for your future reference. Also share it with your friends and colleagues who are having trouble to understand how to upgrade their outdated PHP projects to latest and stable PHP 8.x version.