Upgrading an old PHP app in steps: the order we follow before PHP 8.2 runs out
By the Brightcode team, a small web development agency in Delhi NCR. Reviewed by Gaurav Khokkar, Founder.
A lot of the PHP apps we're asked to look at have the same story. They were built a few years ago, they still work, and nobody has touched the server's PHP version since launch.
That's about to matter for a lot of teams. On the official PHP support calendar, PHP 8.2 gets its last security fixes on 31 December 2026. Everything from 8.1 down is already past end of life. W3Techs' data for 29 October 2026 shows 26.5% of PHP websites still on PHP 7 and 7.7% on PHP 5.
Here's the order we follow when we upgrade one of these apps. Nothing in it is clever. The value is in doing the steps in this order and not skipping any.
1. Write down what's actually running
Before changing anything, record:
- The PHP version on the server (
php -vover SSH, or the hosting panel). - The framework and its version, if there is one. For Laravel:
php artisan --version. - Every PHP extension the app uses (
php -m), because a new PHP build on the server may not have all of them. - Cron jobs, queue workers and anything else that runs outside a web request. These are the parts people forget to test.
Put it in a short UPGRADE.md in the repo. If there's no repo yet, that's step zero: get the code into Git, exactly as it is on the server.
2. Make a backup you've actually restored
A backup you haven't restored is a guess. Dump the database, copy the files, and restore both to a staging server or a local Docker setup. If the app runs there, you have a safe place to break things.
3. Ask Composer what blocks the upgrade
Composer can tell you which packages won't accept the PHP version you want. On the staging copy:
# which installed packages would stop you running PHP 8.3? composer why-not php 8.3 # does this machine meet the lock file's requirements? composer check-platform-reqs # which direct dependencies have newer versions? composer outdated --direct To resolve dependencies as if the server already ran your target version, you can set a platform PHP version in composer.json while you work:
{ "config": { "platform": { "php": "8.3" } } } Remember to update it again when you move to the next version, or remove it if your deploy relies on the real server version.
4. Let Rector do the boring code changes
Rector rewrites code for newer PHP versions: removed functions, changed signatures, new syntax. Start with a dry run so you can read every change first.
<?php // rector.php use Rector\Config\RectorConfig; return RectorConfig::configure() ->withPaths([__DIR__ . '/app', __DIR__ . '/src']) ->withPhpSets(php83: true); vendor/bin/rector process --dry-run Read the diff. Commit Rector's changes separately from your own fixes, so a reviewer can tell machine edits from human ones.
5. Move one step at a time
If an app is on PHP 7.4 and Laravel 8, don't jump to PHP 8.4 and Laravel 13 in one go. Move one framework version at a time, following the official upgrade guide for each, and raise PHP when the framework version needs it. For Laravel, each major version has its own upgrade guide in the docs. A typical bump looks like:
composer require laravel/framework:^12.0 --with-all-dependencies Laravel's own docs say they aim to make each major upgrade doable in a day or less. With older apps, the time goes into third-party packages that need their own upgrades, or have been abandoned and need replacing.
6. Test the paths that make money
Run the test suite if one exists. If not, write a few tests for the paths that matter most before you start, not after: login, the main form or checkout, payment callbacks, emails and one scheduled job. Even a handful of feature tests will catch most of what an upgrade breaks.
Then check by hand on staging:
- Forms submit and the email or WhatsApp notification arrives.
- Payment gateway test mode works end to end, including the callback.
- File uploads, PDF or invoice generation, and image processing (these depend on extensions).
- Cron jobs and queue workers actually run on the new PHP version. Check the CLI version too, because the web server and the command line can use different PHP binaries.
7. Switch production, then watch it
Pick a weekday morning, not a Friday night. Switch the PHP version, deploy, and keep the error log open for the first hour. Keep the old PHP version available on the server for a quick rollback.
If the upgrade also changes URLs, for example you're moving the app to a new framework or domain, that's a migration, not an upgrade. Plan redirects first. Our website migration checklist covers the SEO side.
When it's time to rebuild instead
Upgrading isn't always worth it. We'd consider a rebuild when the app has no framework and the logic is spread across hundreds of files, when key packages are abandoned with no replacement, or when the business needs have changed so much that most screens would be rewritten anyway. Even then, the upgrade notes from step 1 become the spec for the new build. If you're weighing that decision for a business app, this is the kind of work our custom web app development team does with Laravel.
Sources
- PHP supported versions and security dates: https://www.php.net/supported-versions.php (read 29 Oct 2026)
- PHP version share: https://w3techs.com/technologies/details/pl-php (W3Techs, 29 Oct 2026)
- Laravel release notes and support policy: https://laravel.com/docs/13.x/releases
- Rector documentation (PHP sets): https://getrector.com/documentation/set-lists
- Composer CLI docs (
why-not,check-platform-reqs,outdated, platform config): https://getcomposer.org/doc/03-cli.md and https://getcomposer.org/doc/06-config.md#platform
Brightcode is a web development team in Delhi NCR. We upgrade and move older PHP and WordPress sites through our platform migration service, and keep them updated with managed hosting and care.