Skip to content

Commit

Permalink
Merge pull request #1237 from schmittjoh/static-props-access
Browse files Browse the repository at this point in the history
Ensure accessors are cached per property when using reflection
  • Loading branch information
goetas committed Jul 12, 2020
2 parents 224f380 + ff0711b commit 7a33262
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 42 deletions.
81 changes: 41 additions & 40 deletions src/Accessor/DefaultAccessorStrategy.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,33 +65,34 @@ public function getValue(object $object, PropertyMetadata $metadata, Serializati
if (($metadata->expression instanceof Expression) && ($this->evaluator instanceof CompilableExpressionEvaluatorInterface)) {
return $this->evaluator->evaluateParsed($metadata->expression, $variables);
}

return $this->evaluator->evaluate($metadata->expression, $variables);
}

if (null === $metadata->getter) {
if (!isset($this->readAccessors[$metadata->class])) {
if (true === $metadata->forceReflectionAccess) {
$this->readAccessors[$metadata->class] = function ($o, $name) use ($metadata) {
$ref = $this->propertyReflectionCache[$metadata->class][$name] ?? null;
if (null === $ref) {
$ref = new \ReflectionProperty($metadata->class, $name);
$ref->setAccessible(true);
$this->propertyReflectionCache[$metadata->class][$name] = $ref;
}

return $ref->getValue($o);
};
} else {
$this->readAccessors[$metadata->class] = \Closure::bind(static function ($o, $name) {
return $o->$name;
}, null, $metadata->class);
}
if (null !== $metadata->getter) {
return $object->{$metadata->getter}();
}

if ($metadata->forceReflectionAccess) {
$ref = $this->propertyReflectionCache[$metadata->class][$metadata->name] ?? null;
if (null === $ref) {
$ref = new \ReflectionProperty($metadata->class, $metadata->name);
$ref->setAccessible(true);
$this->propertyReflectionCache[$metadata->class][$metadata->name] = $ref;
}

return $this->readAccessors[$metadata->class]($object, $metadata->name);
return $ref->getValue($object);
}

$accessor = $this->readAccessors[$metadata->class] ?? null;
if (null === $accessor) {
$accessor =\Closure::bind(static function ($o, $name) {
return $o->$name;
}, null, $metadata->class);
$this->readAccessors[$metadata->class] = $accessor;
}

return $object->{$metadata->getter}();
return $accessor($object, $metadata->name);
}

/**
Expand All @@ -103,30 +104,30 @@ public function setValue(object $object, $value, PropertyMetadata $metadata, Des
throw new LogicException(sprintf('%s on %s is read only.', $metadata->name, $metadata->class));
}

if (null === $metadata->setter) {
if (!isset($this->writeAccessors[$metadata->class])) {
if (true === $metadata->forceReflectionAccess) {
$this->writeAccessors[$metadata->class] = function ($o, $name, $value) use ($metadata): void {
$ref = $this->propertyReflectionCache[$metadata->class][$name] ?? null;
if (null === $ref) {
$ref = new \ReflectionProperty($metadata->class, $name);
$ref->setAccessible(true);
$this->propertyReflectionCache[$metadata->class][$name] = $ref;
}

$ref->setValue($o, $value);
};
} else {
$this->writeAccessors[$metadata->class] = \Closure::bind(static function ($o, $name, $value): void {
$o->$name = $value;
}, null, $metadata->class);
}
if (null !== $metadata->setter) {
$object->{$metadata->setter}($value);
return;
}

if ($metadata->forceReflectionAccess) {
$ref = $this->propertyReflectionCache[$metadata->class][$metadata->name] ?? null;
if (null === $ref) {
$ref = new \ReflectionProperty($metadata->class, $metadata->name);
$ref->setAccessible(true);
$this->propertyReflectionCache[$metadata->class][$metadata->name] = $ref;
}

$this->writeAccessors[$metadata->class]($object, $metadata->name, $value);
$ref->setValue($object, $value);
return;
}

$object->{$metadata->setter}($value);
$accessor = $this->writeAccessors[$metadata->class] ?? null;
if (null === $accessor) {
$accessor = \Closure::bind(static function ($o, $name, $value): void {
$o->$name = $value;
}, null, $metadata->class);
$this->writeAccessors[$metadata->class] = $accessor;
}
$accessor($object, $metadata->name, $value);
}
}
4 changes: 2 additions & 2 deletions tests/Fixtures/SimpleObjectWithStaticProp.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
class SimpleObjectWithStaticProp
{
/** @Type("string") */
private static $foo;
private $foo;

/**
* @SerializedName("moo")
Expand All @@ -23,7 +23,7 @@ class SimpleObjectWithStaticProp

public function __construct($foo, $bar)
{
self::$foo = $foo;
$this->foo = $foo;
self::$bar = $bar;
}
}

0 comments on commit 7a33262

Please sign in to comment.