Instant Upgrades and Automated Refactoring of any PHP 5.3+ code
Go to file
2020-09-17 09:34:27 +02:00
.docker/php Copy .git directory into docker image 2020-04-03 21:30:47 +02:00
.github Github Actions: add a job which tests the lowest supported versions (#4220) 2020-09-14 21:01:01 +02:00
bin FixMissing Ruleset does not throw SetNotFoundException (#4117) 2020-09-03 15:55:13 +02:00
compiler [CI] Add type-declaration set (#4089) 2020-09-01 17:56:30 +00:00
config [DX] Add Rule that checks that Rule + value object have same starts (#4202) 2020-09-12 23:19:08 +02:00
docs Caching (#4237) 2020-09-16 20:11:35 +02:00
packages Caching (#4237) 2020-09-16 20:11:35 +02:00
rules [StaticRemoval] Various fixes (#4245) 2020-09-17 09:34:27 +02:00
src [StaticRemoval] Various fixes (#4245) 2020-09-17 09:34:27 +02:00
stubs [Doctrine] Add constructor getRepository to service (#3954) 2020-08-13 01:04:23 +02:00
tests Drop YAML config support (#4081) 2020-08-30 23:29:39 +02:00
utils [DX] PHPStan rule to check getNodeTypes() return classes of PhpParser\Node (#4210) 2020-09-12 23:14:31 +00:00
.dockerignore misc 2020-07-27 07:48:51 +02:00
.editorconfig cleanup 2020-04-03 13:24:44 +02:00
.gitattributes misc 2020-07-27 07:48:51 +02:00
.gitignore Fixes #3930 : TypedPropertyRector should not remove DocBlock comment when it specifies the values contained in an array (#4102) 2020-09-02 14:01:45 +02:00
.kodiak.toml [MagicDisclosure] fluent removal improvements 2020-07-31 19:04:51 +02:00
.phpstorm.meta.php PHPStan: require iterable types (#3936) 2020-08-11 10:59:04 +00:00
.travis.yml ci: color 2020-07-22 02:03:18 +02:00
BACKERS.md [SOLID] Add ChangeIfElseValueAssignToEarlyReturnRector 2020-01-06 01:42:15 +01:00
changelog-linker.yaml init CHANGELOG for 0.4.11 2019-04-13 15:16:49 +02:00
CHANGELOG.md update CHANGELOG 2020-08-16 15:50:35 +02:00
CODE_OF_CONDUCT.md Use HTTPS instead of HTTP 2018-02-14 07:23:09 -02:00
composer.json phpstan fixes (#4224) 2020-09-15 11:16:43 +02:00
CONTRIBUTING.md Move contributing guide to its own file 2020-03-21 14:22:10 +01:00
Dockerfile Remove /dev/null from dockerfile for easier debugging 2020-04-20 10:34:51 +02:00
ecs-after-rector.php README + recipe improvements (#4017) 2020-08-24 21:25:26 +00:00
ecs.php [CI] Add type-declaration set (#4089) 2020-09-01 17:56:30 +00:00
LICENSE Update LICENSE year forever 2018-01-02 20:27:07 -02:00
phpstan.neon phpstan fixes (#4224) 2020-09-15 11:16:43 +02:00
phpunit.xml make use of NodeConnectingVisitor + improve generate Rector docs (#3925) 2020-08-07 11:30:05 +02:00
README.md Fixes #3789 add skip Option to exclude files by rule (#4182) 2020-09-12 11:52:08 +02:00
rector-ci.php Caching (#4237) 2020-09-16 20:11:35 +02:00
rector-recipe.php.dist [RemovingStatic] Add SingleStaticServiceToDynamicRector (#4212) 2020-09-13 12:36:29 +02:00
rector.php add ActiveRectorsProvider, fix reporting 0 rules registered (#4106) 2020-09-02 12:54:11 +00:00
sonar-project.properties remove non-existing dir from sonar 2020-09-08 15:06:13 +02:00

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?

Coverage Status Downloads SonarCube



Rector-showcase


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:



Drupal Rector rules


What Can Rector Do for You?


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

There a 2 main ways to use Rector:

  • a single rule, to have the change under control - pick from over 550 rules
  • or group of rules called sets - pick from sets

Sets are suitable for open-source projects and design patterns, like .

To use them, create a rector.php in your root directory:

<?php

// rector.php

declare(strict_types=1);

use Rector\Core\Configuration\Option;
use Rector\Php74\Rector\Property\TypedPropertyRector;
use Rector\Set\ValueObject\SetList;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

return static function (ContainerConfigurator $containerConfigurator): void {
    // get parameters
    $parameters = $containerConfigurator->parameters();

    // here we can define, what sets of rules will be applied
    $parameters->set(Option::SETS, [SetList::CODE_QUALITY]);

    // get services
    $services = $containerConfigurator->services();

    // register single rule
    $services->set(TypedPropertyRector::class);
};

Then dry run Rector:

vendor/bin/rector process src --dry-run

Rector will show you diff of files that it would change. To make the changes, drop --dry-run:

vendor/bin/rector process src

Note: rector.php is loaded by default. For different location, use --config option.


Configuration

<?php

// rector.php

declare(strict_types=1);

use Rector\CodeQuality\Rector\If_\SimplifyIfReturnBoolRector;
use Rector\Core\Configuration\Option;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

return static function (ContainerConfigurator $containerConfigurator): void {
    $parameters = $containerConfigurator->parameters();

    // paths to refactor; solid alternative to CLI arguments
    $parameters->set(Option::PATHS, [__DIR__ . '/src', __DIR__ . '/tests']);

    // is there a file you need to skip?
    $parameters->set(Option::EXCLUDE_PATHS, [
        // single file
        __DIR__ . '/src/ComplicatedFile.php',
        // or directory
        __DIR__ . '/src',
        // or fnmatch
        __DIR__ . '/src/*/Tests/*',
    ]);

    // Rector relies on autoload setup of your project; Composer autoload is included by default; to add more:
    $parameters->set(Option::AUTOLOAD_PATHS, [
        // autoload specific file
        __DIR__ . '/vendor/squizlabs/php_codesniffer/autoload.php',
        // or full directory
        __DIR__ . '/vendor/project-without-composer',
    ]);

    // is there single rule you don't like from a set you use?
    $parameters->set(Option::EXCLUDE_RECTORS, [SimplifyIfReturnBoolRector::class]);

    // is your PHP version different from the one your refactor to? [default: your PHP version]
    $parameters->set(Option::PHP_VERSION_FEATURES, '7.2');

    // auto import fully qualified class names? [default: false]
    $parameters->set(Option::AUTO_IMPORT_NAMES, true);
    // skip root namespace classes, like \DateTime or \Exception [default: true]
    $parameters->set(Option::IMPORT_SHORT_CLASSES, false);
    // skip classes used in PHP DocBlocks, like in /** @var \Some\Class */ [default: true]
    $parameters->set(Option::IMPORT_DOC_BLOCKS, false);

    // skip directory/file by rule
    $parameters->set(Option::SKIP, [
        Rector\CodeQuality\Rector\Array_\CallableThisArrayToAnonymousFunctionRector::class => [
            // single file
            __DIR__ . '/src/ComplicatedFile.php',
            // or directory
            __DIR__ . '/src',
            // or fnmatch
            __DIR__ . '/src/*/Tests/*',
        ],
        Rector\CodeQuality\Rector\Array_\ArrayThisCallToThisMethodCallRector::class => [
            // single file
            __DIR__ . '/src/ComplicatedFile.php',
            // or directory
            __DIR__ . '/src',
            // or fnmatch
            __DIR__ . '/src/*/Tests/*',
        ],
    ]);
};

Configuring Rectors

Every rector can have its own configuration. E.g. the DowngradeTypedPropertyRector rule will add a docblock or not depending on its property ADD_DOC_BLOCK:

<?php

// rector.php

declare(strict_types=1);

use Rector\DowngradePhp74\Rector\Property\DowngradeTypedPropertyRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

return static function (ContainerConfigurator $containerConfigurator): void {
    // Set configuration
    // ...

    // get services
    $services = $containerConfigurator->services();

    // Don't output the docBlocks when removing typed properties
    $services->set(DowngradeTypedPropertyRector::class)
        ->call('configure', [[
            DowngradeTypedPropertyRector::ADD_DOC_BLOCK => false,
        ]]);
};

Ignore Rector Rule in File

For in-file exclusion, use @noRector \FQN name annotation:

<?php

declare(strict_types=1);

class SomeClass
{
    /**
     * @noRector
     */
    public const NAME = '102';

    /**
     * @noRector
     */
    public function foo(): void
    {
        /** @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 a short class name
vendor/bin/rector process src --set solid --only FinalizeClassesWithoutChildrenRector

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

<?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'
    );
};

More Detailed Documentation


How to Contribute

See the contribution guide.


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.php:

docker run --rm -v $(pwd):/project rector/rector:latest process /project/app \
    --config /project/rector.php \
    --autoload-file /project/vendor/autoload.php \
    --dry-run

Debugging

  1. Make sure XDebug is installed and configured
  2. 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:

Known Drawbacks

How to Apply Coding Standards?

Rector uses nikic/php-parser, that build on technology called abstract syntax tree (AST). AST doesn't care about spaces and produces mall-formatted code in both PHP and docblock annotations. 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 ECS and use prepared ecs-after-rector.php set.