Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 004fb4b

Browse files
committed
Implement CallWithDeprecatedIniOptionRule
1 parent 81833b5 commit 004fb4b

File tree

4 files changed

+176
-0
lines changed

4 files changed

+176
-0
lines changed

‎rules.neon‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ rules:
2222
- PHPStan\Rules\Deprecations\CallToDeprecatedFunctionRule
2323
- PHPStan\Rules\Deprecations\CallToDeprecatedMethodRule
2424
- PHPStan\Rules\Deprecations\CallToDeprecatedStaticMethodRule
25+
- PHPStan\Rules\Deprecations\CallWithDeprecatedIniOptionRule
2526
- PHPStan\Rules\Deprecations\FetchingClassConstOfDeprecatedClassRule
2627
- PHPStan\Rules\Deprecations\FetchingDeprecatedConstRule
2728
- PHPStan\Rules\Deprecations\ImplementationOfDeprecatedInterfaceRule
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Rules\Deprecations;
4+
5+
use PhpParser\Node;
6+
use PhpParser\Node\Expr\FuncCall;
7+
use PhpParser\Node\Name;
8+
use PHPStan\Analyser\Scope;
9+
use PHPStan\Broker\FunctionNotFoundException;
10+
use PHPStan\Php\PhpVersion;
11+
use PHPStan\Reflection\ReflectionProvider;
12+
use PHPStan\Rules\Rule;
13+
use PHPStan\Rules\RuleErrorBuilder;
14+
use function count;
15+
use function in_array;
16+
use function sprintf;
17+
use function strtolower;
18+
19+
/**
20+
* @implements Rule<FuncCall>
21+
*/
22+
class CallWithDeprecatedIniOptionRule implements Rule
23+
{
24+
25+
private const INI_FUNCTIONS = [
26+
'ini_get',
27+
'ini_set',
28+
'ini_alter',
29+
'ini_restore',
30+
];
31+
32+
private const DEPRECATED_OPTIONS = [
33+
'assert.active' => 80300,
34+
'assert.exception' => 80300,
35+
'assert.bail' => 80300,
36+
'assert.warning' => 80300,
37+
];
38+
39+
private ReflectionProvider $reflectionProvider;
40+
41+
private DeprecatedScopeHelper $deprecatedScopeHelper;
42+
43+
private PhpVersion $phpVersion;
44+
45+
public function __construct(
46+
ReflectionProvider $reflectionProvider,
47+
DeprecatedScopeHelper $deprecatedScopeHelper,
48+
PhpVersion $phpVersion
49+
)
50+
{
51+
$this->reflectionProvider = $reflectionProvider;
52+
$this->deprecatedScopeHelper = $deprecatedScopeHelper;
53+
$this->phpVersion = $phpVersion;
54+
}
55+
56+
public function getNodeType(): string
57+
{
58+
return FuncCall::class;
59+
}
60+
61+
public function processNode(Node $node, Scope $scope): array
62+
{
63+
if ($this->deprecatedScopeHelper->isScopeDeprecated($scope)) {
64+
return [];
65+
}
66+
67+
if (!($node->name instanceof Name)) {
68+
return [];
69+
}
70+
71+
if (count($node->getArgs()) < 1) {
72+
return [];
73+
}
74+
75+
try {
76+
$function = $this->reflectionProvider->getFunction($node->name, $scope);
77+
} catch (FunctionNotFoundException $e) {
78+
// Other rules will notify if the function is not found
79+
return [];
80+
}
81+
82+
if (!in_array(strtolower($function->getName()), self::INI_FUNCTIONS, true)) {
83+
return [];
84+
}
85+
86+
$phpVersionId = $this->phpVersion->getVersionId();
87+
$iniType = $scope->getType($node->getArgs()[0]->value);
88+
foreach ($iniType->getConstantStrings() as $string) {
89+
if (!array_key_exists($string->getValue(), self::DEPRECATED_OPTIONS)) {
90+
continue;
91+
}
92+
93+
if ($phpVersionId < self::DEPRECATED_OPTIONS[$string->getValue()]) {
94+
continue;
95+
}
96+
97+
return [
98+
RuleErrorBuilder::message(sprintf(
99+
"Call to function %s() with deprecated option '%s'.",
100+
$function->getName(),
101+
$string->getValue(),
102+
))->identifier('function.deprecated')->build(),
103+
];
104+
}
105+
106+
return [];
107+
}
108+
109+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Rules\Deprecations;
4+
5+
use PHPStan\Php\PhpVersion;
6+
use PHPStan\Rules\Rule;
7+
use PHPStan\Testing\RuleTestCase;
8+
use const PHP_VERSION_ID;
9+
10+
/**
11+
* @extends RuleTestCase<CallWithDeprecatedIniOptionRule>
12+
*/
13+
class CallWithDeprecatedIniOptionRuleTest extends RuleTestCase
14+
{
15+
16+
protected function getRule(): Rule
17+
{
18+
return new CallWithDeprecatedIniOptionRule(
19+
$this->createReflectionProvider(),
20+
new DeprecatedScopeHelper([new DefaultDeprecatedScopeResolver()]),
21+
self::getContainer()->getByType(PhpVersion::class),
22+
);
23+
}
24+
25+
public function testRule(): void
26+
{
27+
$expectedErrors = [];
28+
if (PHP_VERSION_ID >= 80300) {
29+
$expectedErrors = [
30+
[
31+
"Call to function ini_set() with deprecated option 'assert.active'.",
32+
11,
33+
],
34+
[
35+
"Call to function ini_get() with deprecated option 'assert.active'.",
36+
12,
37+
],
38+
];
39+
}
40+
41+
$this->analyse(
42+
[__DIR__ . '/data/call-with-deprecation-ini-option.php'],
43+
$expectedErrors,
44+
);
45+
}
46+
47+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace CallWithDeprecatedIniOption;
4+
5+
function doFooBar(): void {
6+
var_dump(ini_set('memory_limit', '2048M'));
7+
var_dump(ini_get('memory_limit'));
8+
}
9+
10+
function doFoo(): void {
11+
var_dump(ini_set('assert.active', false));
12+
var_dump(ini_get('assert.active'));
13+
}
14+
15+
/** @deprecated */
16+
function inDeprecatedFunction(): void {
17+
var_dump(ini_set('assert.active', false));
18+
var_dump(ini_get('assert.active'));
19+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /