Skip to content

Commit 7630ce5

Browse files
committed
Fix phpstan/phpstan#13539: property.notFound in chained isset() with checkDynamicProperties
1 parent 95b0e7f commit 7630ce5

3 files changed

Lines changed: 46 additions & 0 deletions

File tree

src/Rules/Properties/AccessPropertiesCheck.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,10 @@ private function processSingleProperty(Scope $scope, PropertyFetch $node, string
144144
if ($maybePropertyReflection !== null && $maybePropertyReflection->isDummy()->no()) {
145145
return [];
146146
}
147+
148+
if ($type->getObjectClassNames() === []) {
149+
return [];
150+
}
147151
}
148152
}
149153

tests/PHPStan/Rules/Properties/AccessPropertiesRuleTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,4 +1272,18 @@ public function testBug13537(): void
12721272
$this->analyse([__DIR__ . '/data/bug-13537.php'], $errors);
12731273
}
12741274

1275+
public function testBug13539(): void
1276+
{
1277+
$this->checkThisOnly = false;
1278+
$this->checkUnionTypes = true;
1279+
$this->checkDynamicProperties = true;
1280+
$this->analyse([__DIR__ . '/data/bug-13539.php'], [
1281+
[
1282+
'Access to an undefined property object::$baz.',
1283+
26,
1284+
'Learn more: <fg=cyan>https://phpstan.org/blog/solving-phpstan-access-to-undefined-property</>',
1285+
],
1286+
]);
1287+
}
1288+
12751289
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
function broken(string $x): void {
4+
$tmp = json_decode($x, false);
5+
if (!isset($tmp->foo) || !isset($tmp->bar)) {
6+
}
7+
}
8+
9+
function works(string $x): void {
10+
$tmp = json_decode($x, false);
11+
if (!isset($tmp->foo, $tmp->bar)) {
12+
}
13+
}
14+
15+
function works_too(string $x): void {
16+
/** @var stdClass $tmp */
17+
$tmp = json_decode($x, false);
18+
if (!isset($tmp->foo) || !isset($tmp->bar)) {
19+
}
20+
}
21+
22+
function also_ok(mixed $tmp): void {
23+
if (isset($tmp->foo) && isset($tmp->bar)) {
24+
echo $tmp->foo;
25+
echo $tmp->bar;
26+
echo $tmp->baz; // intentional: baz not checked by isset
27+
}
28+
}

0 commit comments

Comments
 (0)