From 25dd2f314903b4a19866cd7e198434e19ba0006d Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Wed, 17 Dec 2025 05:55:16 +0700 Subject: [PATCH 1/2] [Php85] Skip defined int or string on ArrayKeyExistsNullToEmptyStringRector --- .../skip_defined_int_or_string.php.inc | 39 +++++++++++++++++++ .../ArrayKeyExistsNullToEmptyStringRector.php | 13 ++++++- 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 rules-tests/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector/Fixture/skip_defined_int_or_string.php.inc diff --git a/rules-tests/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector/Fixture/skip_defined_int_or_string.php.inc b/rules-tests/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector/Fixture/skip_defined_int_or_string.php.inc new file mode 100644 index 00000000000..0c8fdabc771 --- /dev/null +++ b/rules-tests/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector/Fixture/skip_defined_int_or_string.php.inc @@ -0,0 +1,39 @@ + + */ + private array $todos = [ + 0 => [ + 'unique_key' => 1, + 'label' => 'test 1', + ], + 1 => [ + 'unique_key' => 'fallback_todo', + 'label' => 'fallback todo 1', + ], + ]; + + /** + * @var array + */ + public array $selectedTodos = []; + + public function run(int $index): string + { + if (!array_key_exists($index, $this->todos)) { + return 'Todo not found'; + } + + if (!array_key_exists($this->todos[$index]['unique_key'], $this->selectedTodos)) { + $this->selectedTodos[$this->todos[$index]['unique_key']] = $this->todos[$index]['label']; + return 'Todo selected !'; + } + + return 'Todo already selected !'; + } +} diff --git a/rules/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector.php b/rules/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector.php index 9618aa6afed..d03704e7951 100644 --- a/rules/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector.php +++ b/rules/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector.php @@ -4,6 +4,8 @@ namespace Rector\Php85\Rector\FuncCall; +use PHPStan\Type\UnionType; +use PHPStan\Type\TypeCombinator; use PhpParser\Node; use PhpParser\Node\Expr\FuncCall; use PHPStan\Analyser\Scope; @@ -89,11 +91,20 @@ public function refactor(Node $node): ?Node } $parametersAcceptor = ParametersAcceptorSelectorVariantsWrapper::select($functionReflection, $node, $scope); + $argPosition = $this->argsAnalyzer->resolveArgPosition($args, 'key', 0); + $originalType = $this->getType($args[$argPosition]->value); + + if ($originalType instanceof UnionType) { + $withoutNullParameterType = TypeCombinator::removeNull($originalType); + if ($withoutNullParameterType->equals($originalType)) { + return null; + } + } $result = $this->nullToStrictStringIntConverter->convertIfNull( $node, $args, - $this->argsAnalyzer->resolveArgPosition($args, 'key', 0), + $argPosition, $isTrait, $scope, $parametersAcceptor From 1be9007f82d9553e25c6ee01b8e22511c884cad5 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Wed, 17 Dec 2025 05:58:20 +0700 Subject: [PATCH 2/2] early --- .../Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector.php b/rules/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector.php index d03704e7951..f2f074fd338 100644 --- a/rules/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector.php +++ b/rules/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector.php @@ -90,7 +90,6 @@ public function refactor(Node $node): ?Node return null; } - $parametersAcceptor = ParametersAcceptorSelectorVariantsWrapper::select($functionReflection, $node, $scope); $argPosition = $this->argsAnalyzer->resolveArgPosition($args, 'key', 0); $originalType = $this->getType($args[$argPosition]->value); @@ -101,6 +100,7 @@ public function refactor(Node $node): ?Node } } + $parametersAcceptor = ParametersAcceptorSelectorVariantsWrapper::select($functionReflection, $node, $scope); $result = $this->nullToStrictStringIntConverter->convertIfNull( $node, $args,