Preview diffs before applying and manage project-specific rector.php configurations
Rector can modernize entire codebases automatically, but blindly running a batch over a mature Magento module is a risk. From PhpStorm, every rule can be applied selectively and with a preview, before it actually touches a file.
Table of Contents
- 1. What Rector is good for in a Magento project
- 2. Setting up Rector support in PhpStorm
- 3. Understanding and using a project-specific rector.php in PhpStorm
- 4. Using the diff preview before applying a rule
- 5. Applying individual rules instead of entire rule sets
- 6. Pitfalls of Rector in Magento contexts
- 7. Rector and PHPStan as aligned tools
- 8. Documenting Rector runs traceably for the team
- 9. A practical checklist for safe Rector usage
- 10. Summary
- 11. FAQ
1. What Rector is good for in a Magento project
Rector is a tool for automated code transformation: it reads PHP code as an AST, applies defined rules, and writes the transformed code back. Typical use cases in a Magento project are retrofitting constructor property promotion into older classes, replacing the outdated array() syntax with the short form, or automatically adding type declarations where PHPStan can already infer an unambiguous type.
The decisive difference from a simple search-and-replace operation is that Rector understands the code structurally. A rule such as AddVoidReturnTypeWhereNoReturnRector reliably detects whether a method truly never returns a value, even across several nested control structures, and only then adds the void return type. This makes Rector considerably safer for large-scale modernization than regular expressions.
2. Setting up Rector support in PhpStorm
A dedicated plugin from the PhpStorm marketplace integrates Rector directly into the IDE, so rules no longer have to be run exclusively from the terminal but can be started via right-click on a file or a directory in the project tree. Under the hood the integration still uses the rector/rector package installed via Composer in the project and its configured PHP version, so no separate configuration is needed for the IDE.
For the Mark Shust Docker setup this concretely means Rector gets installed as a dev dependency via bin/composer require --dev rector/rector and is then usable both via bin/cli vendor/bin/rector process and via the PhpStorm integration, provided the IDE's PHP interpreter is correctly mapped to the container.
# Install Rector as a dev dependency
bin/composer require --dev rector/rector
# Test run without changes (dry run) right inside the container
bin/cli vendor/bin/rector process app/code/Mironsoft/SeoSuite --dry-run
3. Understanding and using a project-specific rector.php in PhpStorm
Rector is controlled via a rector.php configuration file in the project root, where rule sets and individual rules are explicitly enabled. For a Magento project it makes sense to deliberately restrict the scope to app/code/Mironsoft and explicitly exclude vendor code and generated files via withSkip(), since Rector would otherwise try to transform Magento core code as well, which is neither sensible nor desired.
PhpStorm reads this rector.php when starting the integration and shows only the rules actually enabled in the project in the rule selection, not the entire Rector rule library. This matters because it prevents accidentally applying a rule that was never intended in the project context, for instance a rule from a level set for a PHP version not yet defined as the project's target.
<?php
declare(strict_types=1);
use Rector\Config\RectorConfig;
use Rector\Php84\Rector\Param\PromoteNullOrFalseFalsyPropertyRector;
use Rector\Set\ValueObject\LevelSetList;
return RectorConfig::configure()
->withPaths([__DIR__ . '/app/code/Mironsoft'])
->withSkip([
__DIR__ . '/vendor',
__DIR__ . '/generated',
])
->withSets([LevelSetList::UP_TO_PHP_84])
->withRules([PromoteNullOrFalseFalsyPropertyRector::class]);
4. Using the diff preview before applying a rule
The central safety mechanism, both in plain CLI usage and in the PhpStorm integration, is dry-run mode. Rector shows a complete diff for every file a rule would change, without actually writing the file. In PhpStorm this diff appears in the IDE's familiar diff viewer, so changes can be reviewed file by file, accepted or discarded individually, instead of blindly accepting an entire batch run.
For a rule such as ClassPropertyAssignToConstructorPromotionRector, which replaces existing property assignments in a constructor with constructor property promotion, this preview pays off especially: for classes with complex constructor logic, such as conditional assignments or extra validation in the constructor body, the automatic transformation can lead to slightly divergent semantics. The diff makes such edge cases visible before they get merged unchecked.
- private StoreManagerInterface $storeManager;
-
- public function __construct(StoreManagerInterface $storeManager)
- {
- $this->storeManager = $storeManager;
- }
+ public function __construct(
+ private readonly StoreManagerInterface $storeManager
+ ) {
+ }
5. Applying individual rules instead of entire rule sets
Instead of applying a complete level set like UP_TO_PHP_84 to an existing module in one pass, it is safer in practice to deliberately select individual rules one after another. The PhpStorm integration lets you pick a single rule from the list of project-enabled rules and apply only that one to a file or directory, which keeps the diff per pass considerably smaller and easier to review.
A proven approach for modernizing an existing Mironsoft module: apply and commit only type-declaration rules first, then separately constructor-property-promotion rules, then array-syntax rules. Each of these steps produces its own, clearly traceable commit, which makes code review noticeably easier compared to a single giant Rector commit with hundreds of lines spanning several unrelated topics.
6. Pitfalls of Rector in Magento contexts
Magento uses reflection-based mechanisms in several places, for instance dependency injection via constructor parameter names in di.xml virtual types or preferences. A Rector rule that renames parameters or automatically changes constructor signatures can, in such cases, cause a silent incompatibility with the XML configuration that only surfaces as an error at runtime, not already at the PHPStan stage.
This is why, in Magento projects, it is important to search specifically for associated di.xml entries referencing the parameter name, for instance in argument-name attributes, after every Rector run touching constructor parameters. PhpStorm helps here through project-wide search for the parameter name, but the check itself is not automated by Rector, it remains a manual follow-up step.
<type name="Mironsoft\SeoSuite\Model\MarkupProvider">
<arguments>
<argument name="storeManager" xsi:type="object">Magento\Store\Model\StoreManagerInterface</argument>
</arguments>
</type>
7. Rector and PHPStan as aligned tools
Rector and PHPStan have a natural order: Rector changes code structurally, PHPStan afterward checks whether the changed code is still type-correct. After every Rector run, even one carefully reviewed with a diff preview, bin/analyse app/code/Mironsoft/SeoSuite --level=5 should therefore be run again to confirm no new level 5 errors were introduced.
In practice, many rules from the TypeDeclarationRector family, such as AddReturnTypeDeclarationRector, actually fix existing PHPStan errors, because they add missing type declarations that PHPStan previously could only derive from PHPDoc or not at all. This way Rector can actively contribute to PHPStan level 5 conformance instead of being just an independent modernization tool.
8. Documenting Rector runs traceably for the team
Because Rector commits often touch many files at once, but are mechanically low-risk in content, it has proven useful to clearly separate them from functional changes and explicitly name the applied rule or rule set in the commit message. A commit like 'Rector: applied ClassPropertyAssignToConstructorPromotionRector to SeoSuite' immediately lets reviewers know this is a mechanical transformation, not a functional change.
For the dual-vendor workflow between the Mironsoft and Abrams copies, this additionally means a Rector run should be executed separately on both paths, since the automatic transformation has no way of knowing that two directories contain structurally identical code. Running Rector only on the Mironsoft copy without the matching run on the Abrams copy would otherwise let the two codebases drift apart gradually.
9. A practical checklist for safe Rector usage
For a controlled Rector deployment on an existing module, the following sequence has proven effective: restrict rector.php to the specific module directory, run a dry run and review the diff completely, apply individual rules rather than whole sets when in doubt, run PHPStan again after applying changes, and finally search specifically for di.xml references to changed constructor parameters.
This sequence turns Rector from a risky batch tool into a controlled part of modernization, where every change was visible before it was actually written. The time savings compared to manual modernization remain intact, only the loss of control from an unsupervised batch run is eliminated.
| Step | Tool | Goal | Risk without this step |
|---|---|---|---|
| Dry run with diff | Rector --dry-run / PhpStorm integration | See changes before they are written | Unnoticed semantic drift |
| Per-rule application | PhpStorm Rector rule selection | Small, traceable commits | Huge, hard-to-review commit |
| di.xml search | PhpStorm project-wide search | Find constructor references | Silent DI incompatibility at runtime |
| PHPStan run afterward | bin/analyse --level=5 | Confirm type correctness after transformation | New, unnoticed type errors |
Mironsoft
PhpStorm setup, Docker integration, and team productivity
PhpStorm that actually runs optimally for Magento and PHP projects?
We review existing PhpStorm setups for slow indexing, unused Docker integration, and missing team conventions, then set up a configuration that is productive from the first second.
Setup Review
Optimizing indexing, interpreter, and memory settings for large Magento projects.
Docker Integration
Cleanly connecting Xdebug, PHPUnit, and database tools to the Docker setup.
Team Conventions
Standardizing inspection profiles, code style, and live templates project-wide.
10. Summary
Rector in PhpStorm: Key Takeaways
Safety net
Dry-run diff in PhpStorm shows every change before it is actually written
Configuration
rector.php limits scope and rules, PhpStorm shows only project-enabled rules
Magento risk
Constructor changes can break di.xml references, manual follow-up required
Follow-up
Run PHPStan again to confirm type correctness after the transformation