Skip to content

Commit 86f68d6

Browse files
Improve support of FILTER_REQUIRE_ARRAY
1 parent a5aa2ce commit 86f68d6

File tree

4 files changed

+36
-14
lines changed

4 files changed

+36
-14
lines changed

src/Type/Php/FilterFunctionReturnTypeHelper.php

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -139,10 +139,11 @@ public function getType(Type $inputType, ?Type $filterType, ?Type $flagsType): T
139139
}
140140

141141
if ($inputType->isScalar()->no() && $inputType->isNull()->no()) {
142-
return $defaultType;
142+
$exactType = $defaultType;
143+
} else {
144+
$exactType = $this->determineExactType($inputType, $filterValue, $defaultType, $flagsType);
143145
}
144146

145-
$exactType = $this->determineExactType($inputType, $filterValue, $defaultType, $flagsType);
146147
$type = $exactType ?? $this->getFilterTypeMap()[$filterValue] ?? $mixedType;
147148
$type = $this->applyRangeOptions($type, $options, $defaultType);
148149

@@ -156,16 +157,19 @@ public function getType(Type $inputType, ?Type $filterType, ?Type $flagsType): T
156157
$type = TypeCombinator::intersect($type, $accessory);
157158
}
158159

159-
if ($hasRequireArrayFlag) {
160-
$type = new ArrayType($inputArrayKeyType ?? $mixedType, $type);
161-
}
162-
163160
if ($exactType === null || $hasOptions->maybe() || (!$inputType->equals($type) && $inputType->isSuperTypeOf($type)->yes())) {
164161
if ($defaultType->isSuperTypeOf($type)->no()) {
165162
$type = TypeCombinator::union($type, $defaultType);
166163
}
167164
}
168165

166+
if ($hasRequireArrayFlag) {
167+
$type = new ArrayType($inputArrayKeyType ?? $mixedType, $type);
168+
if (!$inputIsArray->yes()) {
169+
$type = TypeCombinator::union($type, $defaultType);
170+
}
171+
}
172+
169173
if (!$hasRequireArrayFlag && $hasForceArrayFlag) {
170174
return new ArrayType($inputArrayKeyType ?? $mixedType, $type);
171175
}

tests/PHPStan/Analyser/nsrt/filter-var.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ public function doFoo($mixed, array $stringMixedMap): void
2323
assertType('null', filter_var(17, FILTER_VALIDATE_INT, ['flags' => FILTER_REQUIRE_ARRAY|FILTER_NULL_ON_FAILURE]));
2424
assertType('false', filter_var('foo', FILTER_VALIDATE_INT, ['flags' => FILTER_REQUIRE_ARRAY]));
2525
assertType('null', filter_var('foo', FILTER_VALIDATE_INT, ['flags' => FILTER_REQUIRE_ARRAY|FILTER_NULL_ON_FAILURE]));
26-
assertType('array<int>|false', filter_var($mixed, FILTER_VALIDATE_INT, ['flags' => FILTER_REQUIRE_ARRAY]));
27-
assertType('array<int>|null', filter_var($mixed, FILTER_VALIDATE_INT, ['flags' => FILTER_REQUIRE_ARRAY|FILTER_NULL_ON_FAILURE]));
28-
assertType('array<string, int>|false', filter_var($stringMixedMap, FILTER_VALIDATE_INT, ['flags' => FILTER_REQUIRE_ARRAY]));
29-
assertType('array<string, int>|null', filter_var($stringMixedMap, FILTER_VALIDATE_INT, ['flags' => FILTER_REQUIRE_ARRAY|FILTER_NULL_ON_FAILURE]));
26+
assertType('array<int|false>|false', filter_var($mixed, FILTER_VALIDATE_INT, ['flags' => FILTER_REQUIRE_ARRAY]));
27+
assertType('array<int|null>|null', filter_var($mixed, FILTER_VALIDATE_INT, ['flags' => FILTER_REQUIRE_ARRAY|FILTER_NULL_ON_FAILURE]));
28+
assertType('array<string, int|false>', filter_var($stringMixedMap, FILTER_VALIDATE_INT, ['flags' => FILTER_REQUIRE_ARRAY]));
29+
assertType('array<string, int|null>', filter_var($stringMixedMap, FILTER_VALIDATE_INT, ['flags' => FILTER_REQUIRE_ARRAY|FILTER_NULL_ON_FAILURE]));
3030

3131
assertType('array<17>', filter_var(17, FILTER_VALIDATE_INT, ['flags' => FILTER_FORCE_ARRAY]));
3232
assertType('array<17>', filter_var(17, FILTER_VALIDATE_INT, ['flags' => FILTER_FORCE_ARRAY|FILTER_NULL_ON_FAILURE]));
@@ -41,10 +41,10 @@ public function doFoo($mixed, array $stringMixedMap): void
4141
assertType('null', filter_var(17, FILTER_VALIDATE_INT, ['flags' => FILTER_REQUIRE_ARRAY|FILTER_FORCE_ARRAY|FILTER_NULL_ON_FAILURE]));
4242
assertType('false', filter_var('foo', FILTER_VALIDATE_INT, ['flags' => FILTER_REQUIRE_ARRAY|FILTER_FORCE_ARRAY]));
4343
assertType('null', filter_var('foo', FILTER_VALIDATE_INT, ['flags' => FILTER_REQUIRE_ARRAY|FILTER_FORCE_ARRAY|FILTER_NULL_ON_FAILURE]));
44-
assertType('array<int>|false', filter_var($mixed, FILTER_VALIDATE_INT, ['flags' => FILTER_REQUIRE_ARRAY|FILTER_FORCE_ARRAY]));
45-
assertType('array<int>|null', filter_var($mixed, FILTER_VALIDATE_INT, ['flags' => FILTER_REQUIRE_ARRAY|FILTER_FORCE_ARRAY|FILTER_NULL_ON_FAILURE]));
46-
assertType('array<string, int>|false', filter_var($stringMixedMap, FILTER_VALIDATE_INT, ['flags' => FILTER_REQUIRE_ARRAY|FILTER_FORCE_ARRAY]));
47-
assertType('array<string, int>|null', filter_var($stringMixedMap, FILTER_VALIDATE_INT, ['flags' => FILTER_REQUIRE_ARRAY|FILTER_FORCE_ARRAY|FILTER_NULL_ON_FAILURE]));
44+
assertType('array<int|false>|false', filter_var($mixed, FILTER_VALIDATE_INT, ['flags' => FILTER_REQUIRE_ARRAY|FILTER_FORCE_ARRAY]));
45+
assertType('array<int|null>|null', filter_var($mixed, FILTER_VALIDATE_INT, ['flags' => FILTER_REQUIRE_ARRAY|FILTER_FORCE_ARRAY|FILTER_NULL_ON_FAILURE]));
46+
assertType('array<string, int|false>', filter_var($stringMixedMap, FILTER_VALIDATE_INT, ['flags' => FILTER_REQUIRE_ARRAY|FILTER_FORCE_ARRAY]));
47+
assertType('array<string, int|null>', filter_var($stringMixedMap, FILTER_VALIDATE_INT, ['flags' => FILTER_REQUIRE_ARRAY|FILTER_FORCE_ARRAY|FILTER_NULL_ON_FAILURE]));
4848

4949
assertType('0|int<17, 19>', filter_var($mixed, FILTER_VALIDATE_INT, ['options' => ['default' => 0, 'min_range' => 17, 'max_range' => 19]]));
5050

tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2329,6 +2329,11 @@ public function testBug13434(): void
23292329
$this->analyse([__DIR__ . '/data/bug-13434.php'], []);
23302330
}
23312331

2332+
public function testBug11863(): void
2333+
{
2334+
$this->analyse([__DIR__ . '/data/bug-11863.php'], []);
2335+
}
2336+
23322337
public function testBug13556(): void
23332338
{
23342339
$this->checkExplicitMixed = true;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace Bug11863;
4+
5+
$ips = ['0.0.0.0', '1.2.3.4', '10.0.0.1'];
6+
7+
$ips = array_filter(
8+
filter_var(
9+
$ips,
10+
FILTER_VALIDATE_IP,
11+
FILTER_REQUIRE_ARRAY
12+
)
13+
);

0 commit comments

Comments
 (0)