diff --git a/src/Reflection/ParametersAcceptorSelector.php b/src/Reflection/ParametersAcceptorSelector.php index 04f4917b45..353bafc7e0 100644 --- a/src/Reflection/ParametersAcceptorSelector.php +++ b/src/Reflection/ParametersAcceptorSelector.php @@ -181,7 +181,9 @@ public static function selectFromArgs( $hasTypes = false; $builder = ConstantArrayTypeBuilder::createEmpty(); - foreach ($optArrayType->getIterableKeyType()->getConstantScalarValues() as $optValue) { + foreach ($optArrayType->getIterableKeyType()->getConstantScalarTypes() as $optType) { + $optValue = $optType->getValue(); + if (!is_int($optValue)) { $hasTypes = false; break; @@ -197,6 +199,7 @@ public static function selectFromArgs( $builder->setOffsetValueType( new ConstantIntegerType($optValue), $optValueType, + !$optArrayType->hasOffsetValueType($optType)->yes(), ); } diff --git a/tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php b/tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php index 5f4bb1bf7c..895150be05 100644 --- a/tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php +++ b/tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php @@ -2476,4 +2476,28 @@ public function testClone(): void ]); } + #[RequiresPhp('>= 8.1')] + public function testBug13862(): void + { + $this->analyse([__DIR__ . '/data/bug-13862.php'], []); + } + + #[RequiresPhp('>= 8.1')] + public function testBug13862b(): void + { + $this->analyse([__DIR__ . '/data/bug-13862b.php'], []); + } + + #[RequiresPhp('>= 8.1')] + public function testBug13862c(): void + { + $this->analyse([__DIR__ . '/data/bug-13862c.php'], [ + [ + 'Parameter #2 $options of function curl_setopt_array expects array{10022?: non-empty-string}, array{}|array{10022: 123} given.', + 12, + 'Offset 10022 (non-empty-string) does not accept type 123.', + ], + ]); + } + } diff --git a/tests/PHPStan/Rules/Functions/data/bug-13862.php b/tests/PHPStan/Rules/Functions/data/bug-13862.php new file mode 100644 index 0000000000..d935c2fa36 --- /dev/null +++ b/tests/PHPStan/Rules/Functions/data/bug-13862.php @@ -0,0 +1,66 @@ + $url, + CURLOPT_CONNECTTIMEOUT => 5, + CURLOPT_TIMEOUT => 15, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_PORT => 443, + CURLOPT_ENCODING => "gzip, deflate", + CURLOPT_HTTPHEADER => array("Accept-Encoding: gzip, deflate") + ); + + if ($curl_interface != "") + $options[CURLOPT_INTERFACE] = $curl_interface; + + if ($port !== null) + $options[CURLOPT_PORT] = $port; + + if ($post !== null) { + $options[CURLOPT_POST] = true; + $options[CURLOPT_POSTFIELDS] = $post; + $options[CURLOPT_HTTPHEADER] = array( + "Content-Type: application/json;charset=\"UTF-8\"", + "Accept: application/json", + "Accept-Encoding: gzip, deflate", + "Content-Length: " . mb_strlen($post, "UTF-8") + ); + } + + $curl = curl_init(); + curl_setopt_array($curl, $options); + $rc = curl_exec($curl); + if (is_bool($rc)) + return ""; + else + return $rc; + + } + +} + +$foo = new foo(); +$data = $foo->getUrl("https://example.tld"); diff --git a/tests/PHPStan/Rules/Functions/data/bug-13862b.php b/tests/PHPStan/Rules/Functions/data/bug-13862b.php new file mode 100644 index 0000000000..daaaa4a5de --- /dev/null +++ b/tests/PHPStan/Rules/Functions/data/bug-13862b.php @@ -0,0 +1,12 @@ +