Skip to content

Commit 0c2ff25

Browse files
Getenv
1 parent 74b909a commit 0c2ff25

File tree

6 files changed

+87
-0
lines changed

6 files changed

+87
-0
lines changed

conf/config.neon

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1541,6 +1541,11 @@ services:
15411541
tags:
15421542
- phpstan.broker.dynamicFunctionReturnTypeExtension
15431543

1544+
-
1545+
class: PHPStan\Type\Php\GetenvFunctionReturnTypeExtension
1546+
tags:
1547+
- phpstan.broker.dynamicFunctionReturnTypeExtension
1548+
15441549
-
15451550
class: PHPStan\Type\Php\GetParentClassDynamicFunctionReturnTypeExtension
15461551
tags:

resources/functionMap_php80delta.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@
7878
'imagejpeg' => ['bool', 'im'=>'GdImage', 'filename='=>'string|resource|null', 'quality='=>'int'],
7979
'imagerotate' => ['false|object', 'src_im'=>'resource', 'angle'=>'float', 'bgdcolor'=>'int', 'ignoretransparent='=>'int'],
8080
'imagescale' => ['false|object', 'im'=>'resource', 'new_width'=>'int', 'new_height='=>'int', 'method='=>'int'],
81+
'getenv' => ['array<string, string>|string|false', 'varname'=>'string|null', 'local_only='=>'bool'],
82+
'getenv\'1' => ['array<string, string>'],
8183
'ldap_set_rebind_proc' => ['bool', 'ldap'=>'resource', 'callback'=>'?callable'],
8284
'mb_decode_numericentity' => ['string|false', 'string'=>'string', 'convmap'=>'array', 'encoding='=>'string'],
8385
'mb_encoding_aliases' => ['list<non-falsy-string>', 'encoding'=>'string'],
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Type\Php;
4+
5+
use PhpParser\Node\Expr\FuncCall;
6+
use PHPStan\Analyser\Scope;
7+
use PHPStan\Php\PhpVersion;
8+
use PHPStan\Reflection\FunctionReflection;
9+
use PHPStan\Type\ArrayType;
10+
use PHPStan\Type\Constant\ConstantBooleanType;
11+
use PHPStan\Type\DynamicFunctionReturnTypeExtension;
12+
use PHPStan\Type\StringType;
13+
use PHPStan\Type\Type;
14+
use PHPStan\Type\UnionType;
15+
16+
final class GetenvFunctionReturnTypeExtension implements DynamicFunctionReturnTypeExtension
17+
{
18+
public function isFunctionSupported(FunctionReflection $functionReflection): bool
19+
{
20+
return $functionReflection->getName() === 'getenv';
21+
}
22+
23+
public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): ?Type
24+
{
25+
if (count($functionCall->getArgs()) < 1) {
26+
return null;
27+
}
28+
29+
$argType = $scope->getType($functionCall->getArgs()[0]->value);
30+
if ($argType->isNull()->yes()) {
31+
return new ArrayType(new StringType(), new StringType());
32+
}
33+
if ($argType->isNull()->no()) {
34+
return new UnionType([new StringType(), new ConstantBooleanType(false)]);
35+
}
36+
37+
return null;
38+
}
39+
40+
}

tests/PHPStan/Analyser/NodeScopeResolverTest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@ private static function findTestFiles(): iterable
5757
yield __DIR__ . '/data/explode-php80.php';
5858
}
5959

60+
if (PHP_VERSION_ID < 80000) {
61+
yield __DIR__ . '/data/getenv-php74.php';
62+
} else {
63+
yield __DIR__ . '/data/getenv-php80.php';
64+
}
65+
6066
if (PHP_VERSION_ID >= 80000) {
6167
yield __DIR__ . '/../Reflection/data/unionTypes.php';
6268
yield __DIR__ . '/../Reflection/data/mixedType.php';
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace GetenvPHP74;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
class Foo
8+
{
9+
10+
public function test()
11+
{
12+
assertType('TODO', getenv(null));
13+
assertType('array<string, string>', getenv());
14+
assertType('string|false', getenv('foo'));
15+
}
16+
17+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace GetenvPHP80;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
class Foo
8+
{
9+
10+
public function test()
11+
{
12+
assertType('array<string, string>', getenv(null));
13+
assertType('array<string, string>', getenv());
14+
assertType('string|false', getenv('foo'));
15+
}
16+
17+
}

0 commit comments

Comments
 (0)