Skip to content

Commit f8df7cc

Browse files
committed
Require both __isset and __get for magic property access in array_column
Per PHP docs, both methods must be present for array_column to access non-public properties via magic methods.
1 parent 6aa0b4d commit f8df7cc

File tree

3 files changed

+43
-1
lines changed

3 files changed

+43
-1
lines changed

src/Type/Php/ArrayColumnFunctionReturnTypeExtension.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ private function getOffsetOrProperty(Type $type, Type $offsetOrProperty, Scope $
174174
$property = $type->getProperty($propertyName, $scope);
175175
if (!$scope->canReadProperty($property)) {
176176
foreach ($type->getObjectClassReflections() as $classReflection) {
177-
if ($classReflection->hasMethod('__isset')) {
177+
if ($classReflection->hasMethod('__isset') && $classReflection->hasMethod('__get')) {
178178
return $allowMaybe ? new MixedType() : null;
179179
}
180180
}

tests/PHPStan/Analyser/nsrt/array-column-php82.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,27 @@ public function testFromChild(array $objects): void
298298

299299
}
300300

301+
class ObjectWithIssetOnly
302+
{
303+
private int $priv = 2;
304+
305+
public function __isset(string $name): bool
306+
{
307+
return true;
308+
}
309+
}
310+
311+
class ArrayColumnVisibilityWithIssetOnlyTest
312+
{
313+
314+
/** @param array<int, ObjectWithIssetOnly> $objects */
315+
public function testWithIssetOnly(array $objects): void
316+
{
317+
assertType('array{}', array_column($objects, 'priv'));
318+
}
319+
320+
}
321+
301322
class ArrayColumnVisibilityWithIssetTest
302323
{
303324

tests/PHPStan/Analyser/nsrt/array-column.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,27 @@ public function testFromChild(array $objects): void
312312

313313
}
314314

315+
class ObjectWithIssetOnly
316+
{
317+
private int $priv = 2;
318+
319+
public function __isset(string $name): bool
320+
{
321+
return true;
322+
}
323+
}
324+
325+
class ArrayColumnVisibilityWithIssetOnlyTest
326+
{
327+
328+
/** @param array<int, ObjectWithIssetOnly> $objects */
329+
public function testWithIssetOnly(array $objects): void
330+
{
331+
assertType('array{}', array_column($objects, 'priv'));
332+
}
333+
334+
}
335+
315336
class ArrayColumnVisibilityWithIssetTest
316337
{
317338

0 commit comments

Comments
 (0)