Rector (github.com/rectorphp/rector (https://github.com/rectorphp/rector 10,430 ), 2.6.7, composer require --dev rector/rector) is built on PHPStan 376,908 : it parses code, applies typed rules and prints the result, which makes it the tool for moving PHP 7 code to 8.5.
<?php
use Rector\Config\RectorConfig;
return RectorConfig::configure()
->withPaths([__DIR__ . '/legacy'])
->withPhpSets(php85: true) // every PHP upgrade set up to 8.5
->withPreparedSets(typeDeclarations: true); // infer missing types where provablevendor/bin/rector process --dry-run prints the diff and changes nothing:
...
- switch ($code) {
- case 1: return 'paid';
- case 2: return 'shipped';
- default: return 'pending';
- }
+ return match ($code) {
+ 1 => 'paid',
+ 2 => 'shipped',
+ default => 'pending',
+ };
...
- return count($this->items) ? $this->items[array_key_first($this->items)] : null;
+ return count($this->items) ? array_first($this->items) : null;
...Seven rules fired: constructor promotion, match and str_contains() (PHP 8.0), readonly (8.1), array_first() (8.5), and bool and string return types. Untyped $code and $sku stayed untyped, since nothing proves their types. Run Rector on a clean branch with tests (Testing with PHPUnit), review the diff, then let PHP-CS-Fixer 13,556 tidy the layout. Rector 2.6 already accepts php86: true.