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 1cc1259

Browse files
authored
Bleeding edge - CallWithDeprecatedIniOptionRule
1 parent 81833b5 commit 1cc1259

File tree

4 files changed

+208
-0
lines changed

4 files changed

+208
-0
lines changed

‎rules.neon‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ services:
1616
tags:
1717
- phpstan.deprecations.deprecatedScopeResolver
1818

19+
-
20+
class: PHPStan\Rules\Deprecations\CallWithDeprecatedIniOptionRule
21+
1922
rules:
2023
- PHPStan\Rules\Deprecations\AccessDeprecatedPropertyRule
2124
- PHPStan\Rules\Deprecations\AccessDeprecatedStaticPropertyRule
@@ -33,3 +36,7 @@ rules:
3336
- PHPStan\Rules\Deprecations\TypeHintDeprecatedInFunctionSignatureRule
3437
- PHPStan\Rules\Deprecations\UsageOfDeprecatedCastRule
3538
- PHPStan\Rules\Deprecations\UsageOfDeprecatedTraitRule
39+
40+
conditionalTags:
41+
PHPStan\Rules\Deprecations\CallWithDeprecatedIniOptionRule:
42+
phpstan.rules.rule: %featureToggles.bleedingEdge%
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
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 array_key_exists;
15+
use function count;
16+
use function in_array;
17+
use function sprintf;
18+
use function strtolower;
19+
20+
/**
21+
* @implements Rule<FuncCall>
22+
*/
23+
class CallWithDeprecatedIniOptionRule implements Rule
24+
{
25+
26+
private const INI_FUNCTIONS = [
27+
'ini_get',
28+
'ini_set',
29+
'ini_alter',
30+
'ini_restore',
31+
'get_cfg_var',
32+
];
33+
34+
private const DEPRECATED_OPTIONS = [
35+
// deprecated since unknown version
36+
'mbstring.http_input' => 0,
37+
'mbstring.http_output' => 0,
38+
'mbstring.internal_encoding' => 0,
39+
'pdo_odbc.db2_instance_name' => 0,
40+
'enable_dl' => 0,
41+
42+
'iconv.input_encoding' => 50600,
43+
'iconv.output_encoding' => 50600,
44+
'iconv.internal_encoding' => 50600,
45+
46+
'mbstring.func_overload' => 70200,
47+
'track_errors' => 70200,
48+
49+
'allow_url_include' => 70400,
50+
51+
'assert.quiet_eval' => 80000,
52+
53+
'filter.default' => 80100,
54+
'oci8.old_oci_close_semantics' => 80100,
55+
56+
'assert.active' => 80300,
57+
'assert.exception' => 80300,
58+
'assert.bail' => 80300,
59+
'assert.warning' => 80300,
60+
61+
'session.sid_length' => 80400,
62+
'session.sid_bits_per_character' => 80400,
63+
];
64+
65+
private ReflectionProvider $reflectionProvider;
66+
67+
private DeprecatedScopeHelper $deprecatedScopeHelper;
68+
69+
private PhpVersion $phpVersion;
70+
71+
public function __construct(
72+
ReflectionProvider $reflectionProvider,
73+
DeprecatedScopeHelper $deprecatedScopeHelper,
74+
PhpVersion $phpVersion
75+
)
76+
{
77+
$this->reflectionProvider = $reflectionProvider;
78+
$this->deprecatedScopeHelper = $deprecatedScopeHelper;
79+
$this->phpVersion = $phpVersion;
80+
}
81+
82+
public function getNodeType(): string
83+
{
84+
return FuncCall::class;
85+
}
86+
87+
public function processNode(Node $node, Scope $scope): array
88+
{
89+
if ($this->deprecatedScopeHelper->isScopeDeprecated($scope)) {
90+
return [];
91+
}
92+
93+
if (!($node->name instanceof Name)) {
94+
return [];
95+
}
96+
97+
if (count($node->getArgs()) < 1) {
98+
return [];
99+
}
100+
101+
try {
102+
$function = $this->reflectionProvider->getFunction($node->name, $scope);
103+
} catch (FunctionNotFoundException $e) {
104+
// Other rules will notify if the function is not found
105+
return [];
106+
}
107+
108+
if (!in_array(strtolower($function->getName()), self::INI_FUNCTIONS, true)) {
109+
return [];
110+
}
111+
112+
$phpVersionId = $this->phpVersion->getVersionId();
113+
$iniType = $scope->getType($node->getArgs()[0]->value);
114+
foreach ($iniType->getConstantStrings() as $string) {
115+
if (!array_key_exists($string->getValue(), self::DEPRECATED_OPTIONS)) {
116+
continue;
117+
}
118+
119+
if ($phpVersionId < self::DEPRECATED_OPTIONS[$string->getValue()]) {
120+
continue;
121+
}
122+
123+
return [
124+
RuleErrorBuilder::message(sprintf(
125+
"Call to function %s() with deprecated option '%s'.",
126+
$function->getName(),
127+
$string->getValue(),
128+
))->identifier('function.deprecated')->build(),
129+
];
130+
}
131+
132+
return [];
133+
}
134+
135+
}
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 によって変換されたページ (->オリジナル) /