<?php

namespace BroadwaySerialization\Hydration;

/**
 * Simple implementation of a hydrator, which uses reflection to iterate over the properties of an object
 */
class HydrateUsingReflection implements Hydrate
{
    /**
     * @var array An array of arrays of \ReflectionProperty instances
     */
    private $properties = [];

    /**
     * @inheritdoc
     */
    public function hydrate(array $data, $object)
    {
        foreach ($this->propertiesOf($object) as $name => $property) {
            if (!isset($data[$name])) {
                continue;
            }

            $property->setValue($object, $data[$name]);
        }
    }
    
    /**
     * @param object $object
     * @return \ReflectionProperty[]
     */
    private function propertiesOf($object)
    {
        $className = get_class($object);

        if (!isset($this->properties[$className])) {
            foreach ((new \ReflectionObject($object))->getProperties() as $property) {
                /** @var \ReflectionProperty $property */
                $property->setAccessible(true);
                $this->properties[$className][$property->getName()] = $property;
            }
        }

        return $this->properties[$className];
    }
}

<?php

namespace BroadwaySerialization\Hydration;

/**
 * Simple implementation of a hydrator, which uses reflection to iterate over the properties of an object
 */
class HydrateUsingReflection implements Hydrate
{
    /**
     * @var array An array of arrays of \ReflectionProperty instances
     */
    private $properties = [];

    /**
     * @inheritdoc
     */
    public function hydrate(array $data, $object)
    {
        foreach ($this->propertiesOf($object) as $property) {
            if (!isset($data[$property->getName()])) {
                continue;
            }

            $property->setValue($object, $data[$property->getName()]);
        }
    }

    /**
     * @param object $object
     * @return \ReflectionProperty[]
     */
    private function propertiesOf($object)
    {
        $className = get_class($object);

        if (!isset($this->properties[$className])) {
            $this->properties[$className] = (new \ReflectionObject($object))->getProperties();
            foreach ($this->properties[$className] as $property) {
                /** @var \ReflectionProperty $property */
                $property->setAccessible(true);
            }
        }

        return $this->properties[$className];
    }
}

--- 
+++ 
@@ -17,15 +17,15 @@
      */
     public function hydrate(array $data, $object)
     {
-        foreach ($this->propertiesOf($object) as $property) {
-            if (!isset($data[$property->getName()])) {
+        foreach ($this->propertiesOf($object) as $name => $property) {
+            if (!isset($data[$name])) {
                 continue;
             }
 
-            $property->setValue($object, $data[$property->getName()]);
+            $property->setValue($object, $data[$name]);
         }
     }
-
+    
     /**
      * @param object $object
      * @return \ReflectionProperty[]
@@ -35,10 +35,10 @@
         $className = get_class($object);
 
         if (!isset($this->properties[$className])) {
-            $this->properties[$className] = (new \ReflectionObject($object))->getProperties();
-            foreach ($this->properties[$className] as $property) {
+            foreach ((new \ReflectionObject($object))->getProperties() as $property) {
                 /** @var \ReflectionProperty $property */
                 $property->setAccessible(true);
+                $this->properties[$className][$property->getName()] = $property;
             }
         }
 
Reduce number of ReflectionProperty::getName calls
