doctrine / doctrine-laminas-hydrator

Doctrine hydrators for Laminas applications
https://www.doctrine-project.org/projects/doctrine-laminas-hydrator.html
MIT License
33 stars 19 forks source link

DoctrineObject extractByReference on uninitialized variables (PHP 7.4) #15

Closed javabudd closed 3 years ago

javabudd commented 4 years ago

summary

In php 7.4, variables that are not set have a state of uninitialized. If extracting an entity by reference, extractByReference will fail trying to access an uninitialized property.

expected behavior

Extraction should work with objects that can have uninitialized properties.

proposed solution

Adding a simple isInitialized check before accessing property values

    protected function extractByReference($object)
    {
        $fieldNames = array_merge($this->metadata->getFieldNames(), $this->metadata->getAssociationNames());
        $refl       = $this->metadata->getReflectionClass();
        $filter     = $object instanceof FilterProviderInterface
            ? $object->getFilter()
            : $this->filterComposite;

        $data = [];
        foreach ($fieldNames as $fieldName) {
            if ($filter && ! $filter->filter($fieldName)) {
                continue;
            }

            $reflProperty = $refl->getProperty($fieldName);
            if ($reflProperty->isInitialized($object)) {
                $reflProperty->setAccessible(true);

                $dataFieldName        = $this->computeExtractFieldName($fieldName);
                $data[$dataFieldName] = $this->extractValue($fieldName, $reflProperty->getValue($object), $object);
            }
        }

        return $data;
    }
javabudd commented 4 years ago

I suppose the proposed solution would also need to check if the current version is >= php 7.4 or has the method available

driehle commented 3 years ago

@javabudd I have created PR #20 to solve this issue.

TomHAnderson commented 3 years ago

See https://github.com/doctrine/doctrine-laminas-hydrator/releases/tag/2.1.1