Agentic Experience
This release improves Rector for automated, CI and non-interactive workflows: validate configuration without processing files, limit the amount of changes per run, select multiple rules at once, and get more useful machine-readable output.
- Bump PHPStan to
^2.2.14and PHP-Parser to^5.9, regenerate preload (#8491)
New validate-config command (#8450, #8452)
New validate-config command checks rector.php for configuration issues without processing any source files.
vendor/bin/rector validate-configIt reports deprecated rules and configuration, invalid skips, duplicated rule registrations and other config hygiene issues. A valid config exits with 0, while detected issues exit with 1, so the command can be used directly as a CI gate.
For machine-readable output:
vendor/bin/rector validate-config --output-format=json{
"valid": true,
"issue_count": 0
}Limit a run with --max-changes (#8449)
New --max-changes option lets automated runs process changes in smaller batches:
vendor/bin/rector process --dry-run --max-changes=50The limit counts applied rule changes rather than files. The current file is always finished before Rector stops, so the final number may be slightly above the requested limit.
Run multiple rules with --only (#8451)
--only can now be repeated to run several selected rules in a single pass:
vendor/bin/rector process \
--only=App\\Rector\\FooRector \
--only=App\\Rector\\BarRectorA single --only continues to work as before.
Per-line rule attribution in JSON output (#8448)
JSON output now includes a changes list with the Rector rule and source line for every applied change:
{
"changes": [
{
"rector": "Rector\\Php80\\Rector\\Identical\\StrStartsWithRector",
"line": 38
}
]
}The existing applied_rectors field remains unchanged for backward compatibility.
Cleaner non-interactive output
Non-interactive runs are now quieter and safer:
- Disable progress bar when output is not a TTY (#8444)
- Never emit ANSI escape sequences to non-TTY output, even with
--ansi(#8453) - Do not prompt or automatically create
rector.phpwhen input is non-interactive (#8454)
Sets
- Add
DirnameDirConcatStringToDirectStringPathRectorto the code-quality set (#8470) - Add
NarrowBoolDocblockReturnTypeRectorto the type-declaration-docblocks set (#8484)
Bugfixes 🐛
CompleteDynamicPropertiesRector: skip when a not-autoloaded ancestor may already declare the property (#8441)TypeDeclarationDocblocks: restrict array docblock inference to safer/private cases and avoid narrowing properties with incompatible assignment shapes (#8435, #8436, #8437, #8442)DocblockVarArrayFromPropertyDefaultsRector: widen empty nested array defaults tomixed[]instead ofnever[](#8439, #8474)DocblockReturnArrayFromDirectArrayInstanceRector: skip empty array returns instead of producing an overly narrowarray{}docblock (#8434)IfToNullCoalescingAssignRector: preserve comments inside the convertedif(#8443)RemoveDeadIfBlockRector: keep emptyifwithelseifand trailingelsewhere rewriting would change behavior (#8446)RemoveParentDelegatingClassMethodRector: keep delegating methods carrying annotations such as@Route(#8459)StrContainsRector: skip empty string needles to avoid behavior changes (#8460)- Parallel processing: guard processes that quit before their encoder is initialized, fixing crashes with high worker counts (#8461)
RemoveDeadCatchRector: keep rethrowing catches before catch-allThrowable/Exceptionhandlers (#8462)SimplifyUselessVariableRector: preserve variables referenced by commented-out code and stop folding compound assignments into returns (#8468)ReplaceArgumentDefaultValueRector: avoid re-applying already migrated imported class constants and correctly report applied changes (#8475)- Terminated block detection: ignore trailing comments and recognize terminating infinite loops (#8476)
ForeachToArrayAnyRector: do not dropelseiforelsebranches when converting aforeach(#8480)- Set
Option::SOURCEfrom the actually resolved paths in regular Rector runs (#8424)
Deprecations 💀
--rules-summary- use--output-format=json, which provides applied rules together with files and lines (#8457)DynamicDocBlockPropertyToNativePropertyRector- could change a public-by-design@propertyinto a private native property (#8470)FluentSettersToStandaloneCallMethodRectorandRemoveReturnThisFromSetterClassMethodRector- fluent API semantics are too use-case dependent for a generic transformation (#8473)ListSwapArrayOrderRector- can turn validlist()assignments into broken code; removed from PHP 7.0 sets (#8477)- Remove
RenameDeprecatedMethodCallRector- inferring replacement methods from free-text@deprecateddescriptions is too risky; explicit rename rules are more predictable (#8485)
rector-doctrine 🟠
TypedPropertyFromToOneRelationTypeRector: skip untyped parent property overrides (#520)TypedPropertyFromColumnTypeRector: skip untyped parent property overrides (#521)TypedPropertyFromColumnTypeRector: fix numeric defaults fordecimal/bigintcolumns (#522)TypedPropertyFromColumnTypeRector: make generated property type nullable when anulldefault is present (#523)
rector-phpunit 🟢
- Deprecate
RemoveNamedArgsInDataProviderRector(#782)
rector-symfony 🎵
- Move
EnableValidationAttributesRectorinto the composer-based upgrade path (#1065) ConsoleExecuteReturnIntRector: correctly report changes when rewriting an existing return (#1064)