[PropertyAccess] Fix handling of uninitialized property of anonymous class
This commit is contained in:
parent
4d04a2dd57
commit
27d5edf3d2
|
@ -436,11 +436,11 @@ class PropertyAccessor implements PropertyAccessorInterface
|
|||
}
|
||||
} catch (\Error $e) {
|
||||
// handle uninitialized properties in PHP >= 7.4
|
||||
if (\PHP_VERSION_ID >= 70400 && preg_match('/^Typed property ([\w\\\]+)::\$(\w+) must not be accessed before initialization$/', $e->getMessage(), $matches)) {
|
||||
$r = new \ReflectionProperty($matches[1], $matches[2]);
|
||||
if (\PHP_VERSION_ID >= 70400 && preg_match('/^Typed property ('.preg_quote(get_debug_type($object), '/').')::\$(\w+) must not be accessed before initialization$/', $e->getMessage(), $matches)) {
|
||||
$r = new \ReflectionProperty($class, $matches[2]);
|
||||
$type = ($type = $r->getType()) instanceof \ReflectionNamedType ? $type->getName() : (string) $type;
|
||||
|
||||
throw new AccessException(sprintf('The property "%s::$%s" is not readable because it is typed "%s". You should initialize it or declare a default value instead.', $r->getDeclaringClass()->getName(), $r->getName(), $type), 0, $e);
|
||||
throw new AccessException(sprintf('The property "%s::$%s" is not readable because it is typed "%s". You should initialize it or declare a default value instead.', $matches[1], $r->getName(), $type), 0, $e);
|
||||
}
|
||||
|
||||
throw $e;
|
||||
|
|
|
@ -176,6 +176,41 @@ class PropertyAccessorTest extends TestCase
|
|||
$this->propertyAccessor->getValue($object, 'uninitialized');
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHP 7.4
|
||||
*/
|
||||
public function testGetValueThrowsExceptionIfUninitializedNotNullablePropertyWithGetterOfAnonymousClass()
|
||||
{
|
||||
$this->expectException(AccessException::class);
|
||||
$this->expectExceptionMessage('The property "class@anonymous::$uninitialized" is not readable because it is typed "string". You should initialize it or declare a default value instead.');
|
||||
|
||||
$object = eval('return new class() {
|
||||
private string $uninitialized;
|
||||
|
||||
public function getUninitialized(): string
|
||||
{
|
||||
return $this->uninitialized;
|
||||
}
|
||||
};');
|
||||
|
||||
$this->propertyAccessor->getValue($object, 'uninitialized');
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHP 7.4
|
||||
*/
|
||||
public function testGetValueThrowsExceptionIfUninitializedPropertyOfAnonymousClass()
|
||||
{
|
||||
$this->expectException(AccessException::class);
|
||||
$this->expectExceptionMessage('The property "class@anonymous::$uninitialized" is not readable because it is typed "string". You should initialize it or declare a default value instead.');
|
||||
|
||||
$object = eval('return new class() {
|
||||
public string $uninitialized;
|
||||
};');
|
||||
|
||||
$this->propertyAccessor->getValue($object, 'uninitialized');
|
||||
}
|
||||
|
||||
public function testGetValueThrowsExceptionIfUninitializedPropertyWithGetterOfAnonymousStdClass()
|
||||
{
|
||||
$this->expectException(AccessException::class);
|
||||
|
|
Reference in New Issue