Bugfix 🐛
- [composer-based] Fix fatal error in the
composer-basedcommand on a lazy-initialized property, e.g. PHPStanUnionType::$normalized(#8280)
PHP Fatal error: Uncaught Error: Typed property PHPStan\Type\UnionType::$normalized
must not be accessed before initialization in src/Console/Command/ComposerBasedCommand.php:205
Composer-based sets keep growing: Twig, nette/utils and the rest of Symfony 📦
Follow-up release to 2.6.0. The composer-based rollout continues - Twig and nette/utils join, and every remaining Symfony rule now declares the package version its target API was added in.
use Rector\Config\RectorConfig;
return RectorConfig::configure()
->withComposerBased(
doctrine: true,
netteUtils: true,
phpunit: true,
symfony: true,
twig: true,
);The new Twig composer-based set replaces the twig112 → twig127 → ... → twig30 chain with a single set, where every rule checks the installed twig/twig version:
final class SomeTwigUse
{
- public function run(Twig_Environment $twigEnvironment)
+ public function run(\Twig\Environment $twigEnvironment)
{
- return new Twig_SimpleFilter('some_filter', 'strlen');
+ return new \Twig\TwigFilter('some_filter', 'strlen');
}
}Package bonding (composer-based rollout) 📦
- [NetteUtils] Bind
nette/utilsrules to the installed package version;nette-utils4.phpbecomescomposer-based.phpand is loaded as a single set (#8275) - [rector-symfony] Add Twig composer-based set (#996)
- [rector-symfony] Bond the remaining 48 Symfony rules to their composer package version (#994)
- [rector-symfony] Register
LoadValidatorMetadataToAttributeRectorin the composer-based set - the last interface-bonded rule left outside it (#997) - [rector-symfony] Bond
ContainerInterfaceServiceToServiceContainerRectortosymfony/dependency-injection>=6.0 (#999) - [rector-doctrine] Bond
AddGetReferenceTypeRectortodoctrine/data-fixtures>=1.6 and the annotation-to-attribute sets to their package constraints (#497) - [rector-doctrine] Bond version-specific rules and configuration to composer package constraints (#495) *
- [rector-phpunit] Bond
RemoveExpectAnyFromMockRectorto PHPUnit 11+ (#756) *
* landed in 2.6.0, missing from its release notes
The per-version sets are not touched - every rule stays registered where it was.
Set changes 📈
- [CodingStyle] Remove
ConsistentImplodeRectorfrom the coding style level - the swappedimplode($array, $glue)signature was removed in PHP 8.0, so the rule belongs to thephp80set only, where it already is (#8273) - [rector-doctrine] Add
DoctrineSetList::COMPOSER_BASEDconstant, remove the emptyDOCTRINE_BUNDLE_210set (#499)
Bugfixes 🐛
- [TypeDeclarationDocblocks] Skip docblock reprint when nothing changed in
AddParamArrayDocblockFromAssignsParamToParamReferenceRector(#8271) - [rector-symfony] [Symfony44] Fix duplicated
returninConsoleExecuteReturnIntRectoron a trailing comment (#992), plus a fixture for a block comment with a commented-out return (#993) - [rector-symfony] [Symfony44] Skip redundant
(int)cast on amatchreturn inConsoleExecuteReturnIntRector- amatchof int constants is aUnionType, so theinstanceof IntegerTypecheck missed it (#998)
public function execute(InputInterface $input, OutputInterface $output): int
{
- return (int) match ($input->getArgument('type')) {
+ return match ($input->getArgument('type')) {
'a' => 0,
default => 1,
};
}Deprecations 💀
Deprecated rules still run, but print a warning and will be removed in a future major release.
These are coding standard preferences or opinionated rewrites - a coding standard tool is the better place for them.
rector-src
WrapEncapsedVariableInCurlyBracesRector- also removed from the coding style level (#8272)
function run($world)
{
- echo "Hello $world!";
+ echo "Hello {$world}!";
}The actual PHP 8.2 deprecation, ${var}, is covered by VariableInStringInterpolationFixerRector in the php82 set.
CountArrayToEmptyArrayComparisonRector- also removed from the coding style level (#8274)
-count($array) === 0;
-count($array) > 0;
+$array === [];
+$array !== [];ArraySpreadInsteadOfArrayMergeRector- the spread result is harder to read, and...mid-array looks dangerous in review (#8277)
-$values = array_merge($firstValues, $secondValues);
+$values = [...$firstValues, ...$secondValues];UnusedForeachValueToArrayKeysRector- also removed from the code quality level (#8278)
-foreach ($values as $key => $value) {
+foreach (array_keys($values) as $key) {
$items[$key] = null;
}rector-doctrine
GetRepositoryServiceLocatorToRepositoryServiceInjectionRector- it resolved the repository class by running a regular expression over the entity file contents (#498)
Renames 🔄
- [rector-symfony]
ReplaceServiceArgumentRector→ContainerInterfaceServiceToServiceContainerRector, no longer configurable (#999)
Both sets configured it with the same 2 values, for a single Symfony 6.0 BC break - the Psr\Container\ContainerInterface and Symfony\...\DependencyInjection\ContainerInterface aliases of the service_container service were removed. Now hardcoded, and the ReplaceServiceArgument value object is gone.
use function Symfony\Component\DependencyInjection\Loader\Configurator\service;
-return service(ContainerInterface::class);
+return service('service_container');