@@ -188,6 +188,7 @@ public function __construct(
188188 private ?Scope $ parentScope = null ,
189189 private bool $ nativeTypesPromoted = false ,
190190 private bool $ explicitMixedInUnknownGenericNew = false ,
191+ private bool $ explicitMixedForGlobalVariables = false ,
191192 )
192193 {
193194 if ($ namespace === '' ) {
@@ -465,6 +466,10 @@ public function afterOpenSslCall(string $openSslFunctionName): self
465466 /** @api */
466467 public function hasVariableType (string $ variableName ): TrinaryLogic
467468 {
469+ if ($ this ->isGlobalVariable ($ variableName )) {
470+ return TrinaryLogic::createYes ();
471+ }
472+
468473 $ varExprString = '$ ' . $ variableName ;
469474 if (!isset ($ this ->expressionTypes [$ varExprString ])) {
470475 if ($ this ->canAnyVariableExist ()) {
@@ -495,6 +500,10 @@ public function getVariableType(string $variableName): Type
495500 }
496501 }
497502
503+ if ($ this ->isGlobalVariable ($ variableName )) {
504+ return new ArrayType (new StringType (), new MixedType ($ this ->explicitMixedForGlobalVariables ));
505+ }
506+
498507 if ($ this ->hasVariableType ($ variableName )->no ()) {
499508 throw new UndefinedVariableException ($ this , $ variableName );
500509 }
@@ -528,6 +537,21 @@ public function getDefinedVariables(): array
528537 return $ variables ;
529538 }
530539
540+ private function isGlobalVariable (string $ variableName ): bool
541+ {
542+ return in_array ($ variableName , [
543+ 'GLOBALS ' ,
544+ '_SERVER ' ,
545+ '_GET ' ,
546+ '_POST ' ,
547+ '_FILES ' ,
548+ '_COOKIE ' ,
549+ '_SESSION ' ,
550+ '_REQUEST ' ,
551+ '_ENV ' ,
552+ ], true );
553+ }
554+
531555 /** @api */
532556 public function hasConstant (Name $ name ): bool
533557 {
@@ -2109,6 +2133,7 @@ public function doNotTreatPhpDocTypesAsCertain(): Scope
21092133 $ this ->parentScope ,
21102134 false ,
21112135 $ this ->explicitMixedInUnknownGenericNew ,
2136+ $ this ->explicitMixedForGlobalVariables ,
21122137 );
21132138 }
21142139
@@ -2405,8 +2430,12 @@ public function enterClass(ClassReflection $classReflection): self
24052430 $ this ->isDeclareStrictTypes (),
24062431 null ,
24072432 $ this ->getNamespace (),
2408- array_merge ($ this ->getSuperglobalTypes (), $ this ->getConstantTypes (), ['$this ' => $ thisHolder ]),
2409- array_merge ($ this ->getNativeSuperglobalTypes (), $ this ->getNativeConstantTypes (), ['$this ' => $ thisHolder ]),
2433+ array_merge ($ this ->getConstantTypes (), [
2434+ '$this ' => $ thisHolder ,
2435+ ]),
2436+ array_merge ($ this ->getNativeConstantTypes (), [
2437+ '$this ' => $ thisHolder ,
2438+ ]),
24102439 [],
24112440 null ,
24122441 null ,
@@ -2642,8 +2671,8 @@ private function enterFunctionLike(
26422671 $ this ->isDeclareStrictTypes (),
26432672 $ functionReflection ,
26442673 $ this ->getNamespace (),
2645- array_merge ($ this ->getSuperglobalTypes (), $ this -> getConstantTypes (), $ expressionTypes ),
2646- array_merge ($ this ->getNativeSuperglobalTypes (), $ this -> getNativeConstantTypes (), $ nativeExpressionTypes ),
2674+ array_merge ($ this ->getConstantTypes (), $ expressionTypes ),
2675+ array_merge ($ this ->getNativeConstantTypes (), $ nativeExpressionTypes ),
26472676 );
26482677 }
26492678
@@ -2655,8 +2684,6 @@ public function enterNamespace(string $namespaceName): self
26552684 $ this ->isDeclareStrictTypes (),
26562685 null ,
26572686 $ namespaceName ,
2658- $ this ->getSuperglobalTypes (),
2659- $ this ->getNativeSuperglobalTypes (),
26602687 );
26612688 }
26622689
@@ -2880,8 +2907,8 @@ private function enterAnonymousFunctionWithoutReflection(
28802907 $ this ->isDeclareStrictTypes (),
28812908 $ this ->getFunction (),
28822909 $ this ->getNamespace (),
2883- array_merge ($ this ->getSuperglobalTypes (), $ this -> getConstantTypes (), $ expressionTypes ),
2884- array_merge ($ this ->getNativeSuperglobalTypes (), $ this -> getNativeConstantTypes (), $ nativeTypes ),
2910+ array_merge ($ this ->getConstantTypes (), $ expressionTypes ),
2911+ array_merge ($ this ->getNativeConstantTypes (), $ nativeTypes ),
28852912 [],
28862913 $ this ->inClosureBindScopeClass ,
28872914 new TrivialParametersAcceptor (),
@@ -4963,34 +4990,4 @@ private function getNativeConstantTypes(): array
49634990 return $ constantTypes ;
49644991 }
49654992
4966- /** @return array<string, ExpressionTypeHolder> */
4967- private function getSuperglobalTypes (): array
4968- {
4969- $ superglobalTypes = [];
4970- $ exprStrings = ['$GLOBALS ' , '$_SERVER ' , '$_GET ' , '$_POST ' , '$_FILES ' , '$_COOKIE ' , '$_SESSION ' , '$_REQUEST ' , '$_ENV ' ];
4971- foreach ($ this ->expressionTypes as $ exprString => $ typeHolder ) {
4972- if (!in_array ($ exprString , $ exprStrings , true )) {
4973- continue ;
4974- }
4975-
4976- $ superglobalTypes [$ exprString ] = $ typeHolder ;
4977- }
4978- return $ superglobalTypes ;
4979- }
4980-
4981- /** @return array<string, ExpressionTypeHolder> */
4982- private function getNativeSuperglobalTypes (): array
4983- {
4984- $ superglobalTypes = [];
4985- $ exprStrings = ['$GLOBALS ' , '$_SERVER ' , '$_GET ' , '$_POST ' , '$_FILES ' , '$_COOKIE ' , '$_SESSION ' , '$_REQUEST ' , '$_ENV ' ];
4986- foreach ($ this ->nativeExpressionTypes as $ exprString => $ typeHolder ) {
4987- if (!in_array ($ exprString , $ exprStrings , true )) {
4988- continue ;
4989- }
4990-
4991- $ superglobalTypes [$ exprString ] = $ typeHolder ;
4992- }
4993- return $ superglobalTypes ;
4994- }
4995-
49964993}
0 commit comments