diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/VariableFetchAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/VariableFetchAnalyzer.php index 2d7f5bca7cc..26ecddde3be 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/VariableFetchAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/VariableFetchAnalyzer.php @@ -650,11 +650,9 @@ public static function getGlobalType(string $var_id, int $codebase_analysis_php_ $bool_string_helper = new Union([new TBool(), new TString()]); $bool_string_helper->possibly_undefined = true; - $detailed_type = new TKeyedArray([ + $detailed_type_members = [ // https://www.php.net/manual/en/reserved.variables.server.php 'PHP_SELF' => $non_empty_string_helper, - 'argv' => $argv_helper, - 'argc' => $argc_helper, 'GATEWAY_INTERFACE' => $non_empty_string_helper, 'SERVER_ADDR' => $non_empty_string_helper, 'SERVER_NAME' => $non_empty_string_helper, @@ -727,7 +725,15 @@ public static function getGlobalType(string $var_id, int $codebase_analysis_php_ // phpunit 'APP_DEBUG' => $bool_string_helper, 'APP_ENV' => $string_helper, - ]); + ]; + + if ($var_id === '$_SERVER') { + // those elements are not usually present in $_ENV + $detailed_type_members['argc'] = $argc_helper; + $detailed_type_members['argv'] = $argv_helper; + } + + $detailed_type = new TKeyedArray($detailed_type_members); // generic case for all other elements $detailed_type->previous_key_type = Type::getNonEmptyString(); diff --git a/tests/SuperGlobalsTest.php b/tests/SuperGlobalsTest.php index d13919f2345..ad052fd56b3 100644 --- a/tests/SuperGlobalsTest.php +++ b/tests/SuperGlobalsTest.php @@ -22,5 +22,14 @@ function returnsList(): array { ', 'assertions' => [] ]; + + yield 'ENV has scalar entries only' => [ + ' */ + function f(): array { + return $_ENV; + } + ' + ]; } }