Doctrine entity object to array

前端 未结 8 651
星月不相逢
星月不相逢 2020-12-16 13:10

Wants to convert doctrine entiry object to normal array, this is my code so far,

 $demo = $this->doctrine->em->find(\'Entity\\User\',2);


        
相关标签:
8条回答
  • 2020-12-16 14:05

    I made a recursive function in my Repository a few months ago, it's not perfect (like, if you have a field createdBy and updatedBy, it will only retrieve the value for one user because of a rather simple protection against recursivity with $aClassNamesDone), but it may help:

        public function entityToArray($entity, &$aClassNamesDone=array(), $latestClassName="") {
    
        $result = array();
    
        if(is_null($entity)) {
            return $result;
        }
    
        $className = get_class($entity);
    
        // init with calling entity
        if(empty($aClassNamesDone)) {
            $aClassNamesDone[] =$className;
        }
    
        $uow = $this->getEntityManager()->getUnitOfWork();
    
        $entityPersister = $uow->getEntityPersister($className);
        $classMetadata = $entityPersister->getClassMetadata();
    
        //DEPENDS ON DOCTRINE VERSION
        //if(strstr($className, 'DoctrineProxies\\__CG__\\')){
        if(strstr($className, 'Proxies\\__CG__\\')){
            $uow->initializeObject($entity);
        }
    
        foreach ($uow->getOriginalEntityData($entity) as $field => $value) {
    
            if (isset($classMetadata->associationMappings[$field])) {
    
                $assoc = $classMetadata->associationMappings[$field];
    
                if (isset($classMetadata->columnNames[$field])) {
                    $columnName = $classMetadata->columnNames[$field];
                    $result[$columnName] = $value;
                }
    
                // to avoid recursivity we can look for the owning side (gives similar results as Query::HYDRATE_ARRAY):
                // elseif($assoc['isOwningSide']) { ...
                // or we can track entities explored and avoid any duplicates (this will however ignore some fields pointing to the same entity class)
                // for example: only one of createdBy, updatedBy will be kept
    
                else if(!in_array($assoc['targetEntity'], $aClassNamesDone) || $assoc['targetEntity'] == $latestClassName) {
    
                    try {
    
                        if ($assoc['targetEntity'] != 'Timestamp') {
    
                            $aClassNamesDone[] = $assoc['targetEntity'];
    
                            $targetClass = $this->getEntityManager()->getClassMetadata($assoc['targetEntity']);
    
                            if (($assoc['type'] == \Doctrine\ORM\Mapping\ClassMetadata::MANY_TO_MANY) || ($assoc['type'] == \Doctrine\ORM\Mapping\ClassMetadata::ONE_TO_MANY)) {
    
                                $getterName = 'get' . ucfirst($assoc['fieldName']);
                                $entityChildren = $entity->$getterName();
                                foreach ($entityChildren as $oneChild) {
                                    $result[$assoc['fieldName']][] = $this->getEntityManager()->getRepository($assoc['targetEntity'])->entityToArray($oneChild, $aClassNamesDone, $assoc['targetEntity']);
                                }
    
                            } else if (($assoc['type'] == \Doctrine\ORM\Mapping\ClassMetadata::ONE_TO_ONE) || ($assoc['type'] == \Doctrine\ORM\Mapping\ClassMetadata::MANY_TO_ONE)) {
    
                                $getterName = 'get' . ucfirst($assoc['fieldName']);
                                $entityChild = $entity->$getterName();
                                $result[$assoc['fieldName']] = $this->getEntityManager()->getRepository($assoc['targetEntity'])->entityToArray($entityChild, $aClassNamesDone, $assoc['targetEntity']);
    
                            }
                        }
    
                    } catch (\Exception $e) {
                        //var_dump('No entityToArray for ' . $assoc['targetEntity']);
                        throw ($e);
                    }
                }
    
            }
        }
    
        return $result;
    }
    
    0 讨论(0)
  • 2020-12-16 14:13

    If you alread have the object entity fetched form the database, you could also work with the DoctrineModule\Stdlib\Hydrator\DoctrineObject.

    /**
     * Assume your entity for which you want to create an array is in $entityObject.
     * And it is an instance of YourEntity::class.
     */
    $tmpObject = new DoctrineObject($this->entityManager, YourEntity::class);
    $data = $tmpObject->extract($entityObject);
    

    Now $data will contain your object as array.

    P.S. I'm not sure this was possible when the question was asked.

    0 讨论(0)
提交回复
热议问题