Symfony\Component\Serializer\Normalizer\AbstractNormalizer::instantiateObject PHP Method

instantiateObject() protected method

This method also allows to denormalize data into an existing object if it is present in the context with the object_to_populate. This object is removed from the context before being returned to avoid side effects when recursively normalizing an object graph.
protected instantiateObject ( array &$data, string $class, array &$context, ReflectionClass $reflectionClass, array | boolean $allowedAttributes ) : object
$data array
$class string
$context array
$reflectionClass ReflectionClass
$allowedAttributes array | boolean
return object
    protected function instantiateObject(array &$data, $class, array &$context, \ReflectionClass $reflectionClass, $allowedAttributes)
    {
        if (func_num_args() >= 6) {
            $format = func_get_arg(5);
        } else {
            if (__CLASS__ !== get_class($this)) {
                $r = new \ReflectionMethod($this, __FUNCTION__);
                if (__CLASS__ !== $r->getDeclaringClass()->getName()) {
                    @trigger_error(sprintf('Method %s() will have a 6th `$format = null` argument in version 4.0. Not defining it is deprecated since 3.2.', get_class($this), __FUNCTION__), E_USER_DEPRECATED);
                }
            }
            $format = null;
        }
        if (isset($context[static::OBJECT_TO_POPULATE]) && is_object($context[static::OBJECT_TO_POPULATE]) && $context[static::OBJECT_TO_POPULATE] instanceof $class) {
            $object = $context[static::OBJECT_TO_POPULATE];
            unset($context[static::OBJECT_TO_POPULATE]);
            return $object;
        }
        $constructor = $this->getConstructor($data, $class, $context, $reflectionClass, $allowedAttributes);
        if ($constructor) {
            $constructorParameters = $constructor->getParameters();
            $params = array();
            foreach ($constructorParameters as $constructorParameter) {
                $paramName = $constructorParameter->name;
                $key = $this->nameConverter ? $this->nameConverter->normalize($paramName) : $paramName;
                $allowed = $allowedAttributes === false || in_array($paramName, $allowedAttributes);
                $ignored = in_array($paramName, $this->ignoredAttributes);
                if (method_exists($constructorParameter, 'isVariadic') && $constructorParameter->isVariadic()) {
                    if ($allowed && !$ignored && (isset($data[$key]) || array_key_exists($key, $data))) {
                        if (!is_array($data[$paramName])) {
                            throw new RuntimeException(sprintf('Cannot create an instance of %s from serialized data because the variadic parameter %s can only accept an array.', $class, $constructorParameter->name));
                        }
                        $params = array_merge($params, $data[$paramName]);
                    }
                } elseif ($allowed && !$ignored && (isset($data[$key]) || array_key_exists($key, $data))) {
                    $parameterData = $data[$key];
                    try {
                        if (null !== $constructorParameter->getClass()) {
                            if (!$this->serializer instanceof DenormalizerInterface) {
                                throw new LogicException(sprintf('Cannot create an instance of %s from serialized data because the serializer inject in "%s" is not a denormalizer', $constructorParameter->getClass(), static::class));
                            }
                            $parameterClass = $constructorParameter->getClass()->getName();
                            $parameterData = $this->serializer->denormalize($parameterData, $parameterClass, $format, $context);
                        }
                    } catch (\ReflectionException $e) {
                        throw new RuntimeException(sprintf('Could not determine the class of the parameter "%s".', $key), 0, $e);
                    }
                    // Don't run set for a parameter passed to the constructor
                    $params[] = $parameterData;
                    unset($data[$key]);
                } elseif ($constructorParameter->isDefaultValueAvailable()) {
                    $params[] = $constructorParameter->getDefaultValue();
                } else {
                    throw new RuntimeException(sprintf('Cannot create an instance of %s from serialized data because its constructor requires parameter "%s" to be present.', $class, $constructorParameter->name));
                }
            }
            if ($constructor->isConstructor()) {
                return $reflectionClass->newInstanceArgs($params);
            } else {
                return $constructor->invokeArgs(null, $params);
            }
        }
        return new $class();
    }