Doctrine entity object to array

2020-02-10 14:18发布

问题:

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

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

Getting entity object ,

Entity\User Object
(
[id:Entity\User:private] => 2
[username:Entity\User:private] => TestUser
[password:Entity\User:private] => 950715f3f83e20ee154995cd5a89ac75
[email:Entity\User:private] => test@test.com
[firm_id:Entity\User:private] => Entity\Firm Object
    (
        [id:Entity\Firm:private] => 16
        [company_name:Entity\Firm:private] => TestFirm
        [company_detail:Entity\Firm:private] => India
        [created_at:Entity\Firm:private] => DateTime Object
            (
                [date] => 2014-08-01 18:16:08
                [timezone_type] => 3
                [timezone] => Europe/Paris
            )

        [user:Entity\Firm:private] => 
    )

[created_at:Entity\User:private] => DateTime Object
    (
        [date] => 2014-08-01 15:12:36
        [timezone_type] => 3
        [timezone] => Europe/Paris
    )

[updated_at:Entity\User:private] => DateTime Object
    (
        [date] => 2014-08-01 15:12:36
        [timezone_type] => 3
        [timezone] => Europe/Paris
    )

[firm:protected] => 
) ,

Tried this ,But as per my requiremnet do not want to user doctrine_query. Thanks.

回答1:

You can try something like this,

    $result = $this->em->createQueryBuilder();
    $app_code = $result->select('p')
            ->from('YourUserBundle:User', 'p')
            ->where('p.id= :id')
            ->setParameter('id', 2)
            ->getQuery()
            ->getResult(\Doctrine\ORM\Query::HYDRATE_ARRAY);

Another way,

 $this->em->getRepository('YourUserBundle:User')
      ->findBy(array('id'=>1));

Above will return an array but contains doctrine objects. Best way to return an array is using the doctrine query.

Hope this helps. Cheers!



回答2:

Note: If your reason for wanting an array representation of an entity is to convert it to JSON for an AJAX response, I recommend checking this Q&A: How to encode Doctrine entities to JSON in Symfony 2.0 AJAX application?. I particularly like the one about using the built-in JsonSerializable interface which is similar to my answer.


Since Doctrine does not provide a way to convert entities to associative arrays, you would have to do it yourself. One easy way is to create a base class that exposes a function that returns an array representation of the entity. This could be accomplished by having the base class function call get_object_vars on itself. This functions gets the accessible properties of the passed-in object and returns them as an associative array. Then you would simply have to extend this base class whenever you create an entity that you would want to convert to an array.

Here is a very simple example:

abstract class ArrayExpressible {
    public function toArray() {
        return get_object_vars($this);
    }
}

/** @Entity */
class User extends ArrayExpressible {

    /** @Id @Column(type="integer") @GeneratedValue */
    protected $id = 1; // initialized to 1 for testing

    /** @Column(type="string") */
    protected $username = 'abc';

    /** @Column(type="string") */
    protected $password = '123';

}

$user = new User();
print_r($user->toArray());
// Outputs: Array ( [id] => 1 [username] => abc [password] => 123 )

Note: You must make the entity's properties protected so the base class can access them using get_object_vars()


If for some reason you cannot extend from a base class (perhaps because you already extend a base class), you could at least create an interface and make sure your entities implement the interface. Then you will have to implement the toArray function inside each entity.

Example:

interface ArrayExpressible {
    public function toArray();
}

/** @Entity */
class User extends SomeBaseClass implements ArrayExpressible {

    /** @Id @Column(type="integer") @GeneratedValue */
    protected $id = 1; // initialized to 1 for testing

    /** @Column(type="string") */
    protected $username = 'abc';

    /** @Column(type="string") */
    protected $password = '123';

    public function toArray() {
        return get_object_vars($this);
        // alternatively, you could do:
        // return ['username' => $this->username, 'password' => '****']
    }

}

$user = new User;
print_r($user->toArray());
// Outputs: Array ( [id] => 1 [username] => abc [password] => 123 )


回答3:

I'm new to Symfony, but there is some working (but strange) way:

json_decode($this->container->get('serializer')->serialize($entity, 'json'))



回答4:

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;
}


回答5:

If you just need to access a single value, you can also do this...

If 'personType' were an object and you wanted the value of the relationship...

$personTypeId = $form->get('personType')->getViewData();


回答6:

Simply u can use this

$demo=array($demo);