Skip to content

Commit 560ee10

Browse files
kevcomparadisenicolas-grekas
authored andcommitted
[PropertyAccess] Fix accessing public property in Object
1 parent 7c12ac1 commit 560ee10

File tree

5 files changed

+76
-1
lines changed

5 files changed

+76
-1
lines changed

src/Symfony/Component/PropertyAccess/PropertyAccessor.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ private function readProperty(array $zval, string $property, bool $ignoreInvalid
408408
}
409409
} elseif (self::ACCESS_TYPE_PROPERTY === $access[self::ACCESS_TYPE]) {
410410
$name = $access[self::ACCESS_NAME];
411-
if (!method_exists($object, '__get') && !isset($object->$name) && !\array_key_exists($name, (array) $object) && (\PHP_VERSION_ID < 70400 || !(new \ReflectionProperty($class, $name))->hasType())) {
411+
if ($access[self::ACCESS_REF] && !isset($object->$name) && !\array_key_exists($name, (array) $object) && (\PHP_VERSION_ID < 70400 || !(new \ReflectionProperty($class, $name))->hasType())) {
412412
throw new AccessException(sprintf('The property "%s::$%s" is not initialized.', $class, $name));
413413
}
414414

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
namespace Symfony\Component\PropertyAccess\Tests\Fixtures;
4+
5+
#[\AllowDynamicProperties]
6+
class TestPublicPropertyDynamicallyCreated
7+
{
8+
public function __construct(string $bar)
9+
{
10+
$this->foo = $bar;
11+
}
12+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
namespace Symfony\Component\PropertyAccess\Tests\Fixtures;
4+
5+
class TestPublicPropertyGetterOnObject
6+
{
7+
public $a = 'A';
8+
private $b = 'B';
9+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace Symfony\Component\PropertyAccess\Tests\Fixtures;
4+
5+
class TestPublicPropertyGetterOnObjectMagicGet
6+
{
7+
public $a = 'A';
8+
private $b = 'B';
9+
10+
public function __get($property)
11+
{
12+
if ('b' === $property) {
13+
return $this->b;
14+
}
15+
}
16+
}

src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestClassMagicGet;
3030
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestClassSetValue;
3131
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestClassTypeErrorInsideCall;
32+
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestPublicPropertyDynamicallyCreated;
33+
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestPublicPropertyGetterOnObject;
34+
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestPublicPropertyGetterOnObjectMagicGet;
3235
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestSingularAndPluralProps;
3336
use Symfony\Component\PropertyAccess\Tests\Fixtures\Ticket5775Object;
3437
use Symfony\Component\PropertyAccess\Tests\Fixtures\TypeHinted;
@@ -849,4 +852,39 @@ public function testSetterNeedsPublicAccess()
849852
$object = new TestClassSetValue(0);
850853
$this->propertyAccessor->setValue($object, 'foo', 1);
851854
}
855+
856+
public function testGetPublicProperty()
857+
{
858+
$value = 'A';
859+
$path = 'a';
860+
$object = new TestPublicPropertyGetterOnObject();
861+
862+
$this->assertSame($value, $this->propertyAccessor->getValue($object, $path));
863+
}
864+
865+
public function testGetPrivateProperty()
866+
{
867+
$object = new TestPublicPropertyGetterOnObject();
868+
869+
$this->expectException(NoSuchPropertyException::class);
870+
$this->expectExceptionMessageMatches('/.*Neither the property "b" nor one of the methods/');
871+
$this->propertyAccessor->getValue($object, 'b');
872+
}
873+
874+
public function testGetDynamicPublicProperty()
875+
{
876+
$value = 'Bar';
877+
$path = 'foo';
878+
$object = new TestPublicPropertyDynamicallyCreated('Bar');
879+
880+
$this->assertSame($value, $this->propertyAccessor->getValue($object, $path));
881+
}
882+
883+
public function testGetDynamicPublicPropertyWithMagicGetterAllow()
884+
{
885+
$value = 'B';
886+
$path = 'b';
887+
$object = new TestPublicPropertyGetterOnObjectMagicGet();
888+
$this->assertSame($value, $this->propertyAccessor->getValue($object, $path));
889+
}
852890
}

0 commit comments

Comments
 (0)