12 KiB
Rector - Upgrade Your Legacy App to a Modern Codebase
Rector is a reconstructor tool - it does instant upgrades and instant refactoring of your code. Why refactor manually if Rector can handle 80% of the task for you?
Sponsors
Rector grows faster with your help, the more you help the more work it saves you. Check out Rector's Patreon. One-time donations are welcome through PayPal.
Thank you:
Open-Source First
Rector instantly upgrades and instantly refactors the PHP code of your application.
It supports all versions of PHP from 5.2 and many open-source projects:
What Can Rector Do for You?
- Upgrade 30 000 unit tests from PHPUnit 6 to 9 in 2 weeks
- Complete @var annotations or parameter/return type declarations
- Complete PHP 7.4 property type declarations
- Upgrade your code from PHP 5.3 to 8.0
- Migrate your project from Nette to Symfony
- Refactor Laravel facades to dependency injection
- And much more...
How to Apply Coding Standards?
Rector uses nikic/php-parser, that build on technology called abstract syntax tree) technology* (AST). AST doesn't care about spaces and produces mall-formatted code. That's why your project needs to have coding standard tool and set of rules, so it can make refactored nice and shiny again.
Don't have any coding standard tool? Add EasyCodingStandard and use prepared ecs-after-rector.php
set.
Install
composer require rector/rector --dev
- Having conflicts during
composer require
? → Use the Rector Prefixed - Using a different PHP version than Rector supports? → Use the Docker image
Running Rector
A. Prepared Sets
Featured open-source projects have prepared sets. You can find them in /config/set
or by autocomplete of Rector\Set\ValueObject\SetList
constants in rector.php
config.
Let's say you pick the symfony40
set and you want to upgrade your /src
directory:
vendor/bin/rector process src --set symfony40 --dry-run
Rector will show you diff of files that it would change. To make the changes, drop --dry-run
:
# apply upgrades to your code
vendor/bin/rector process src --set symfony40
Some sets, such as code-quality
can be used on a regular basis. The best practise is to use config over command line:
<?php
// rector.php
declare(strict_types=1);
use Rector\Core\Configuration\Option;
use Rector\Set\ValueObject\SetList;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$parameters = $containerConfigurator->parameters();
$parameters->set(Option::SETS, [SetList::CODE_QUALITY]);
};
PHP config format is a new Symfony best practice.
B. Standalone Rules
In the end, it's best to combine few of basic sets and drop particular rules that you want to try:
# rector.yaml
parameters:
sets:
- code-quality
services:
Rector\Php74\Rector\Property\TypedPropertyRector: null
Then let Rector refactor your code:
vendor/bin/rector process src
👍
Note: rector.yaml
is loaded by default. For different location, use --config
option.
Features
Paths
If you're annoyed by repeating paths in arguments, you can move them to config instead:
# rector.yaml
parameters:
paths:
- 'src'
- 'tests'
Extra Autoloading
Rector relies on whatever autoload setup the project it is fixing is using by using the Composer autoloader as default. To specify your own autoload file, use --autoload-file
option:
vendor/bin/rector process ../project --autoload-file ../project/vendor/autoload.php
Or use a rector.yaml
configuration file:
# rector.yaml
parameters:
autoload_paths:
- 'vendor/squizlabs/php_codesniffer/autoload.php'
- 'vendor/project-without-composer'
Exclude Paths and Rectors
You can also exclude files or directories (with regex or fnmatch):
# rector.yaml
parameters:
exclude_paths:
- '*/src/*/Tests/*'
You can use a whole set, except 1 rule:
# rector.yaml
parameters:
exclude_rectors:
- 'Rector\CodeQuality\Rector\If_\SimplifyIfReturnBoolRector'
For in-file exclusion, use @noRector \FQN name
annotation:
class SomeClass
{
/**
* @noRector \Rector\DeadCode\Rector\ClassMethod\RemoveEmptyClassMethodRector
*/
public function foo()
{
/** @noRector \Rector\DeadCode\Rector\Plus\RemoveDeadZeroAndOneOperationRector */
round(1 + 0);
}
}
Run Just 1 Rector Rule
Do you have config that includes many sets and Rectors? You might want to run only a single Rector. The --only
argument allows that, e.g.:
vendor/bin/rector process src --set solid --only Rector\SOLID\Rector\Class_\FinalizeClassesWithoutChildrenRector
Or just short name:
vendor/bin/rector process src --set solid --only FinalizeClassesWithoutChildrenRector
Both will run only Rector\SOLID\Rector\Class_\FinalizeClassesWithoutChildrenRector
.
Provide PHP Version
By default Rector uses the language features matching your system version of PHP. You can configure it for a different PHP version:
# rector.yaml
parameters:
php_version_features: '7.2' # your version is 7.3
Safe Types
In default setting:
# rector.yaml
parameters:
safe_types: false
All docblocks are taken seriously, e.g. with typed properties rule:
<?php
class ValueObject
{
- public $value;
+ public string $value;
/**
* @param string $value
*/
public function __construct($value)
{
$this->value = $value;
}
}
Do you want to use only explicit PHP type declaration? Enable safe_types
:
# rector.yaml
parameters:
safe_types: true
Then, docblocks are skipped:
<?php
class ValueObject
{
public $value;
- public $count;
+ public int $count;
/**
* @param string $value
*/
public function __construct($value, int $count)
{
$this->value = $value;
$this->count = $count
}
}
Import Use Statements
FQN classes are not imported by default. If you don't want to do it manually after every Rector run, enable it by:
# rector.yaml
parameters:
auto_import_names: true
You can also fine-tune how these imports are processed:
# rector.yaml
parameters:
# this will not import root namespace classes, like \DateTime or \Exception
import_short_classes: false
# this will not import classes used in PHP DocBlocks, like in /** @var \Some\Class */
import_doc_blocks: false
Limit Execution to Changed Files
Execution can be limited to changed files using the process
option --match-git-diff
.
This option will filter the files included by the configuration, creating an intersection with the files listed in git diff
.
vendor/bin/rector process src --match-git-diff
This option is useful in CI with pull-requests that only change few files.
Symfony Container
To work with some Symfony rules, you now need to link your container XML file
# rector.yaml
parameters:
# path to load services from
symfony_container_xml_path: 'var/cache/dev/AppKernelDevDebugContainer.xml'
More Detailed Documentation
- All Rectors Overview
- Create own Rule
- Generate Rector from Recipe
- How Does Rector Work?
- PHP Parser Nodes Overview
- Add Checkstyle with your CI
How to Contribute
Run Rector in Docker
You can run Rector on your project using Docker:
docker run --rm -v $(pwd):/project rector/rector:latest process /project/src --set symfony40 --dry-run
# Note that a volume is mounted from `pwd` (the current directory) into `/project` which can be accessed later.
Using rector.yaml
:
docker run --rm -v $(pwd):/project rector/rector:latest process /project/app \
--config /project/rector.yaml \
--autoload-file /project/vendor/autoload.php \
--dry-run
Debugging
- Make sure XDebug is installed and configured
- Add
--xdebug
option when running Rector
Without XDebug, you can use --debug
option, that will print nested exceptions output.
Community Packages
Do you use Rector to upgrade your code? Add it here: