2019-10-25 00:59:42 +00:00
# Rector - Upgrade Your Legacy App to a Modern Codebase
2017-07-15 17:20:20 +00:00
2018-09-11 18:46:11 +00:00
Rector is a **rec**onstruc**tor** tool - it does **instant upgrades** and **instant refactoring** of your code.
2020-03-21 10:41:11 +00:00
Why refactor manually if Rector can handle 80% of the task for you?
2018-02-02 16:51:41 +00:00
2018-11-09 13:45:14 +00:00
[![Coverage Status ](https://img.shields.io/coveralls/rectorphp/rector/master.svg?style=flat-square )](https://coveralls.io/github/rectorphp/rector?branch=master)
2018-07-02 13:02:27 +00:00
[![Downloads ](https://img.shields.io/packagist/dt/rector/rector.svg?style=flat-square )](https://packagist.org/packages/rector/rector)
2020-07-30 22:30:25 +00:00
[![SonarCube ](https://img.shields.io/badge/SonarCube_Debt-%3C27-brightgreen.svg?style=flat-square )](https://sonarcloud.io/dashboard?id=rectorphp_rector)
2017-07-15 17:20:20 +00:00
2020-02-21 14:26:02 +00:00
< br >
2020-04-14 19:52:27 +00:00
- **[Online DEMO](https://getrector.org/demo)**
2020-06-17 10:12:34 +00:00
- [Explore 500+ Rector Rules ](/docs/rector_rules_overview.md )
2020-02-21 14:26:02 +00:00
2020-05-03 12:32:03 +00:00
---
2020-02-13 16:13:49 +00:00
2019-10-19 10:42:36 +00:00
![Rector-showcase ](docs/images/rector-showcase-var.gif )
2018-01-13 15:01:31 +00:00
2019-04-29 21:42:11 +00:00
< br >
## Sponsors
Rector grows faster with your help, the more you help the more work it saves you.
2020-03-21 10:41:11 +00:00
Check out [Rector's Patreon ](https://www.patreon.com/rectorphp ). One-time donations are welcome [through PayPal ](https://www.paypal.me/rectorphp ).
2019-04-29 21:42:11 +00:00
2019-08-19 13:49:41 +00:00
Thank you:
2020-06-18 10:38:01 +00:00
< p >
2020-06-18 10:43:11 +00:00
< a href = "https://www.startupjobs.cz/en/startup/scrumworks-s-r-o" > < img src = "/docs/images/amateri.png" > < / a >
< img src = "/docs/images/space.png" width = 40 >
2020-06-17 12:16:17 +00:00
< a href = "https://zenika.ca/en/en" > < img src = "/docs/images/zenika.png" > < / a >
< img src = "/docs/images/space.png" width = 40 >
< a href = "https://spaceflow.io/en" > < img src = "/docs/images/spaceflow.png" > < / a >
< / p >
2019-08-19 13:49:41 +00:00
2019-04-29 21:42:11 +00:00
< br >
## Open-Source First
2020-05-03 12:32:37 +00:00
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:
2017-07-15 17:20:20 +00:00
2018-10-21 09:00:39 +00:00
< br >
2017-10-30 15:00:28 +00:00
< p align = "center" >
2019-06-08 20:41:52 +00:00
< a href = "/config/set/php" > < img src = "/docs/images/php.png" > < / a >
2019-10-20 14:46:52 +00:00
< img src = "/docs/images/space.png" width = 40 >
2019-06-08 20:41:52 +00:00
< a href = "/config/set/symfony" > < img src = "/docs/images/symfony.png" > < / a >
2019-10-20 14:46:52 +00:00
< img src = "/docs/images/space.png" width = 40 >
2019-10-20 14:47:40 +00:00
< a href = "/config/set/laravel" > < img src = "/docs/images/laravel.png" > < / a >
2020-05-25 00:36:40 +00:00
< img src = "/docs/images/space.png" width = 40 >
< a href = "/config/set/twig" > < img src = "/docs/images/twig.png" > < / a >
2019-10-20 14:47:40 +00:00
< br >
2020-05-25 00:29:13 +00:00
< a href = "https://github.com/palantirnet/drupal-rector/tree/master/config/drupal-8" > < img src = "/docs/images/drupal.png" alt = "Drupal Rector rules" > < / a >
< img src = "/docs/images/space.png" width = 40 >
2019-10-20 14:47:40 +00:00
< a href = "/config/set/cakephp" > < img src = "/docs/images/cakephp.png" > < / a >
< img src = "/docs/images/space.png" width = 40 >
2019-11-04 00:48:08 +00:00
< a href = "/config/set/phpunit" > < img src = "/docs/images/phpunit.png" > < / a >
2017-10-30 15:00:28 +00:00
< / p >
2017-08-20 15:40:19 +00:00
2018-10-21 09:00:39 +00:00
< br >
2019-10-25 00:59:42 +00:00
## What Can Rector Do for You?
2018-08-01 20:29:01 +00:00
2020-06-17 10:12:34 +00:00
- [Upgrade 30 000 unit tests from PHPUnit 6 to 9 in 2 weeks ](https://twitter.com/LBajsarowicz/status/1272947900016967683 )
- Complete [@var annotations or parameter/return type declarations ](https://www.tomasvotruba.com/blog/2019/01/03/how-to-complete-type-declarations-without-docblocks-with-rector/ )
2020-01-14 21:20:38 +00:00
- [Complete PHP 7.4 property type declarations ](https://www.tomasvotruba.com/blog/2018/11/15/how-to-get-php-74-typed-properties-to-your-code-in-few-seconds/ )
2020-06-17 10:12:34 +00:00
- Upgrade your code from **PHP 5.3 to 8.0**
- [Migrate your project from Nette to Symfony ](https://www.tomasvotruba.com/blog/2019/02/21/how-we-migrated-from-nette-to-symfony-in-3-weeks-part-1/ )
2020-01-14 21:20:38 +00:00
- [Refactor Laravel facades to dependency injection ](https://www.tomasvotruba.com/blog/2019/03/04/how-to-turn-laravel-from-static-to-dependency-injection-in-one-day/ )
2017-12-28 19:58:35 +00:00
- And much more...
2017-07-15 17:20:20 +00:00
2019-07-09 15:05:10 +00:00
## How to Apply Coding Standards?
2020-08-12 09:09:31 +00:00
Rector uses [nikic/php-parser ](https://github.com/nikic/PHP-Parser/ ), that build on technology called *abstract syntax tree* (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.
2019-07-09 16:17:03 +00:00
2020-07-16 15:51:53 +00:00
Don't have any coding standard tool? Add [EasyCodingStandard ](https://github.com/Symplify/EasyCodingStandard ) and use prepared [`ecs-after-rector.php` ](/ecs-after-rector.php ) set.
2019-11-08 17:02:29 +00:00
2017-07-15 17:20:20 +00:00
## Install
```bash
2018-10-06 17:28:57 +00:00
composer require rector/rector --dev
2017-07-15 17:20:20 +00:00
```
2020-05-03 12:32:03 +00:00
- Having conflicts during `composer require` ? → Use the [Rector Prefixed ](https://github.com/rectorphp/rector-prefixed )
- Using a different PHP version than Rector supports? → Use the [Docker image ](#run-rector-in-docker )
2018-01-06 15:50:22 +00:00
2019-11-08 16:49:03 +00:00
## Running Rector
2020-05-03 12:19:09 +00:00
### A. Prepared Sets
2019-11-08 16:49:03 +00:00
2020-07-20 12:18:15 +00:00
Featured open-source projects have **prepared sets** . You can find them in [`/config/set` ](/config/set ) or by autocomplete of [`Rector\Set\ValueObject\SetList` ](/packages/set/src/ValueObject/SetList.php ) constants in `rector.php` config.
2019-11-08 16:49:03 +00:00
2020-07-20 12:18:15 +00:00
Let's say you pick the [`symfony40` ](/config/set/symfony40.php ) set and you want to upgrade your `/src` directory:
2019-11-08 16:49:03 +00:00
```bash
vendor/bin/rector process src --set symfony40 --dry-run
```
2020-07-20 12:18:15 +00:00
Rector will show you diff of files that it *would* change. To *make* the changes, drop `--dry-run` :
2020-05-03 12:19:09 +00:00
2019-11-08 16:49:03 +00:00
```bash
# apply upgrades to your code
vendor/bin/rector process src --set symfony40
```
2020-07-29 16:28:19 +00:00
Some sets, such as [`code-quality` ](/config/set/code-quality.php ) can be used on a regular basis. **The best practice is to use config over command line** :
2020-07-18 18:26:57 +00:00
```php
< ?php
2020-07-20 12:18:15 +00:00
// rector.php
2020-07-18 18:26:57 +00:00
declare(strict_types=1);
use Rector\Core\Configuration\Option;
2020-07-20 12:18:15 +00:00
use Rector\Set\ValueObject\SetList;
2020-07-18 18:26:57 +00:00
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$parameters = $containerConfigurator->parameters();
2020-07-20 12:18:15 +00:00
$parameters->set(Option::SETS, [SetList::CODE_QUALITY]);
2020-07-18 18:26:57 +00:00
};
```
2020-07-20 12:18:15 +00:00
PHP config format is a new [Symfony best practice ](https://twitter.com/symfony_en/status/1284538366147678208 ).
2020-05-03 12:19:09 +00:00
### B. Standalone Rules
2019-11-08 16:49:03 +00:00
2020-05-03 12:22:23 +00:00
In the end, it's best to combine few of basic sets and drop [particular rules ](/docs/rector_rules_overview.md ) that you want to try:
2019-11-08 16:49:03 +00:00
2020-07-29 16:28:19 +00:00
```php
< ?php
// rector.php
declare(strict_types=1);
2019-11-08 16:49:03 +00:00
2020-07-29 16:28:19 +00:00
use Rector\Core\Configuration\Option;
use Rector\Set\ValueObject\SetList;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Rector\Php74\Rector\Property\TypedPropertyRector;
return static function (ContainerConfigurator $containerConfigurator): void {
$parameters = $containerConfigurator->parameters();
$services = $containerConfigurator->services();
$services->set(TypedPropertyRector::class);
$parameters->set(Option::SETS, [SetList::CODE_QUALITY]);
};
2020-05-03 12:19:09 +00:00
```
2019-11-08 16:49:03 +00:00
2020-05-03 12:30:47 +00:00
Then let Rector refactor your code:
2019-11-08 16:49:03 +00:00
2020-05-03 12:19:09 +00:00
```bash
vendor/bin/rector process src
```
:+1:
< br >
2020-07-29 16:28:19 +00:00
*Note: `rector.php` is loaded by default. For different location, use `--config` option.*
2019-11-08 16:49:03 +00:00
## Features
2020-05-13 16:17:21 +00:00
### Paths
If you're annoyed by repeating paths in arguments, you can move them to config instead:
2020-07-29 16:28:19 +00:00
```php
< ?php
// rector.php
declare(strict_types=1);
use Rector\Core\Configuration\Option;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$parameters = $containerConfigurator->parameters();
$parameters->set(Option::PATHS, [
__DIR__ . '/src',
__DIR__ . '/tests',
]);
};
2020-05-13 16:17:21 +00:00
```
2018-02-08 14:25:45 +00:00
### Extra Autoloading
2020-03-21 10:41:11 +00:00
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:
2018-02-09 00:16:54 +00:00
2018-02-08 14:25:45 +00:00
```bash
2018-02-08 14:27:14 +00:00
vendor/bin/rector process ../project --autoload-file ../project/vendor/autoload.php
2018-02-08 14:25:45 +00:00
```
2020-07-29 16:28:19 +00:00
Or use a `rector.php` configuration file:
```php
< ?php
// rector.php
declare(strict_types=1);
use Rector\Core\Configuration\Option;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
2018-04-13 19:14:07 +00:00
2020-07-29 16:28:19 +00:00
return static function (ContainerConfigurator $containerConfigurator): void {
$parameters = $containerConfigurator->parameters();
$parameters->set(Option::AUTOLOAD_PATHS, [
__DIR__ . '/vendor/squizlabs/php_codesniffer/autoload.php',
__DIR__ . '/vendor/project-without-composer',
]);
};
2018-04-13 19:14:07 +00:00
```
2019-11-08 12:08:42 +00:00
### Exclude Paths and Rectors
2019-01-18 11:41:07 +00:00
2018-11-09 13:58:49 +00:00
You can also **exclude files or directories** (with regex or [fnmatch ](http://php.net/manual/en/function.fnmatch.php )):
2018-08-29 20:45:09 +00:00
2020-07-29 16:28:19 +00:00
```php
< ?php
// rector.php
declare(strict_types=1);
use Rector\Core\Configuration\Option;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$parameters = $containerConfigurator->parameters();
$parameters->set(Option::EXCLUDE_PATHS, [
__DIR__ . '/src/*/Tests/*',
]);
};
2018-08-29 20:45:09 +00:00
```
2020-05-13 16:17:21 +00:00
You can use a whole set, except 1 rule:
2019-01-18 11:41:07 +00:00
2020-07-29 16:28:19 +00:00
```php
< ?php
// rector.php
declare(strict_types=1);
use Rector\CodeQuality\Rector\If_\SimplifyIfReturnBoolRector;
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,
]);
$parameters->set(Option::EXCLUDE_RECTORS, [
SimplifyIfReturnBoolRector::class,
]);
};
2019-01-18 11:41:07 +00:00
```
2020-05-13 16:17:21 +00:00
For in-file exclusion, use `@noRector \FQN name` annotation:
2019-12-29 12:00:38 +00:00
```php
class SomeClass
{
/**
* @noRector \Rector\DeadCode\Rector\ClassMethod\RemoveEmptyClassMethodRector
*/
public function foo()
{
/** @noRector \Rector\DeadCode\Rector\Plus\RemoveDeadZeroAndOneOperationRector */
round(1 + 0);
}
}
```
2020-06-17 12:39:26 +00:00
### Run Just 1 Rector Rule
2020-06-17 12:33:58 +00:00
2020-06-17 12:39:26 +00:00
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.:
2020-06-17 12:33:58 +00:00
```bash
2020-06-17 12:39:26 +00:00
vendor/bin/rector process src --set solid --only Rector\SOLID\Rector\Class_\FinalizeClassesWithoutChildrenRector
2020-06-17 12:33:58 +00:00
```
2020-06-17 12:39:26 +00:00
Or just short name:
2020-06-17 12:33:58 +00:00
2020-06-17 12:39:26 +00:00
```bash
vendor/bin/rector process src --set solid --only FinalizeClassesWithoutChildrenRector
```
Both will run only `Rector\SOLID\Rector\Class_\FinalizeClassesWithoutChildrenRector` .
2020-06-17 12:33:58 +00:00
2019-11-08 12:08:42 +00:00
### Provide PHP Version
2019-10-25 00:59:42 +00:00
By default Rector uses the language features matching your system version of PHP. You can configure it for a different PHP version:
2019-02-23 13:03:07 +00:00
2020-07-29 16:28:19 +00:00
```php
< ?php
// rector.php
declare(strict_types=1);
use Rector\Core\Configuration\Option;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$parameters = $containerConfigurator->parameters();
$parameters->set(Option::PHP_VERSION_FEATURES, '7.2'); # your version is 7.3
};
2019-02-23 13:03:07 +00:00
```
2020-06-16 19:43:45 +00:00
### Safe Types
2020-06-19 16:03:37 +00:00
In default setting:
2020-06-16 19:43:45 +00:00
2020-07-29 16:28:19 +00:00
```php
< ?php
// rector.php
declare(strict_types=1);
use Rector\Core\Configuration\Option;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$parameters = $containerConfigurator->parameters();
$parameters->set(Option::SAFE_TYPES, false);
};
2020-06-16 19:43:45 +00:00
```
All docblocks are taken seriously, e.g. with [typed properties ](https://github.com/rectorphp/rector/blob/master/docs/rector_rules_overview.md#typedpropertyrector ) rule:
```diff
< ?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` :
2020-07-29 16:28:19 +00:00
```php
< ?php
// rector.php
declare(strict_types=1);
use Rector\Core\Configuration\Option;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$parameters = $containerConfigurator->parameters();
$parameters->set(Option::SAFE_TYPES, true);
};
2020-06-16 19:43:45 +00:00
```
Then, docblocks are skipped:
```diff
< ?php
class ValueObject
{
public $value;
- public $count;
+ public int $count;
/**
* @param string $value
*/
2020-06-16 21:06:16 +00:00
public function __construct($value, int $count)
2020-06-16 19:43:45 +00:00
{
$this->value = $value;
$this->count = $count
}
}
```
2019-11-08 12:08:42 +00:00
### Import Use Statements
2020-04-04 20:59:33 +00:00
FQN classes are not imported by default. If you don't want to do it manually after every Rector run, enable it by:
2019-10-12 15:51:07 +00:00
2020-07-29 16:28:19 +00:00
```php
< ?php
// rector.php
declare(strict_types=1);
use Rector\Core\Configuration\Option;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$parameters = $containerConfigurator->parameters();
$parameters->set(Option::AUTO_IMPORT_NAMES, true);
};
2019-10-12 15:51:07 +00:00
```
2019-12-20 06:40:36 +00:00
You can also fine-tune how these imports are processed:
2019-12-12 15:05:12 +00:00
2020-07-29 16:28:19 +00:00
```php
< ?php
// rector.php
declare(strict_types=1);
use Rector\Core\Configuration\Option;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$parameters = $containerConfigurator->parameters();
2019-12-20 06:40:36 +00:00
2020-07-29 16:28:19 +00:00
// this will not import root namespace classes, like \DateTime or \Exception
$parameters->set(Option::IMPORT_SHORT_CLASSES, false);
// this will not import classes used in PHP DocBlocks, like in /** @var \Some\Class */
$parameters->set(Option::IMPORT_DOC_BLOCKS, false);
};
2019-12-12 15:05:12 +00:00
```
2019-11-23 20:30:52 +00:00
### Limit Execution to Changed Files
2019-11-24 00:00:46 +00:00
Execution can be limited to changed files using the `process` option `--match-git-diff` .
2019-11-23 20:30:52 +00:00
This option will filter the files included by the configuration, creating an intersection with the files listed in `git diff` .
2019-11-24 00:00:46 +00:00
```bash
vendor/bin/rector process src --match-git-diff
```
This option is useful in CI with pull-requests that only change few files.
2019-11-23 20:30:52 +00:00
2019-12-16 14:45:37 +00:00
### Symfony Container
To work with some Symfony rules, you now need to link your container XML file
2020-07-29 16:28:19 +00:00
```php
< ?php
// rector.php
declare(strict_types=1);
use Rector\Core\Configuration\Option;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$parameters = $containerConfigurator->parameters();
$parameters->set(Option::SYMFONY_CONTAINER_XML_PATH_PARAMETER, __DIR__ . '/var/cache/dev/AppKernelDevDebugContainer.xml');
};
2019-12-16 14:45:37 +00:00
```
2020-05-13 16:17:21 +00:00
< br >
2017-12-28 19:58:35 +00:00
## More Detailed Documentation
2017-10-15 09:07:53 +00:00
2020-05-03 12:22:23 +00:00
- **[All Rectors Overview](/docs/rector_rules_overview.md)**
- [Create own Rule ](/docs/create_own_rule.md )
- [Generate Rector from Recipe ](/docs/rector_recipe.md )
- [How Does Rector Work? ](/docs/how_it_works.md )
- [PHP Parser Nodes Overview ](/docs/nodes_overview.md )
- [Add Checkstyle with your CI ](/docs/checkstyle.md )
2017-10-15 09:07:53 +00:00
2020-05-13 16:17:21 +00:00
< br >
2017-12-28 19:58:35 +00:00
## How to Contribute
2017-07-15 17:20:20 +00:00
2020-03-21 11:00:05 +00:00
See [the contribution guide ](/CONTRIBUTING.md ).
2018-12-12 09:02:10 +00:00
2020-05-13 16:17:21 +00:00
< br >
2018-12-31 19:27:38 +00:00
## Run Rector in Docker
2020-05-03 12:19:09 +00:00
2019-10-25 00:59:42 +00:00
You can run Rector on your project using Docker:
2018-12-31 19:27:38 +00:00
2018-12-12 09:02:10 +00:00
```bash
2020-06-03 10:19:07 +00:00
docker run --rm -v $(pwd):/project rector/rector:latest process /project/src --set symfony40 --dry-run
2019-03-11 14:12:27 +00:00
2019-10-26 01:11:11 +00:00
# Note that a volume is mounted from `pwd` (the current directory) into `/project` which can be accessed later.
2018-12-11 17:22:54 +00:00
```
2019-03-11 14:27:13 +00:00
2020-07-29 16:28:19 +00:00
Using `rector.php` :
2019-03-11 14:27:13 +00:00
```bash
2020-06-03 10:19:07 +00:00
docker run --rm -v $(pwd):/project rector/rector:latest process /project/app \
2020-07-29 16:28:19 +00:00
--config /project/rector.php \
2020-03-21 13:23:09 +00:00
--autoload-file /project/vendor/autoload.php \
--dry-run
2019-03-11 14:27:13 +00:00
```
2019-04-02 13:40:53 +00:00
2020-05-13 16:17:21 +00:00
< br >
2020-07-07 15:58:55 +00:00
### Debugging
2020-07-07 15:59:41 +00:00
1. Make sure XDebug is installed and configured
2. Add `--xdebug` option when running Rector
2020-07-07 15:58:55 +00:00
2020-07-07 15:59:41 +00:00
Without XDebug, you can use `--debug` option, that will print nested exceptions output.
2020-07-07 15:58:55 +00:00
< br >
2020-05-13 16:17:21 +00:00
## Community Packages
2019-04-02 13:40:53 +00:00
2019-10-25 00:59:42 +00:00
Do you use Rector to upgrade your code? Add it here:
2019-04-02 13:40:53 +00:00
2020-04-17 21:13:29 +00:00
- [palantirnet/drupal-rector ](https://github.com/palantirnet/drupal-rector ) by [Palantir.net ](https://github.com/palantirnet ) for [Drupal ](https://www.drupal.org/ )
2019-10-25 01:04:18 +00:00
- [sabbelasichon/typo3-rector ](https://github.com/sabbelasichon/typo3-rector ) for [TYPO3 ](https://typo3.org/ )