web-dev-qa-db-ja.com

Doctrineエンティティオブジェクトから配列へ

doctrine entryオブジェクトを通常の配列に変換したい、これはこれまでの私のコードです、

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

エンティティオブジェクトの取得、

Entity\User Object
(
[id:Entity\User:private] => 2
[username:Entity\User:private] => TestUser
[password:Entity\User:private] => 950715f3f83e20ee154995cd5a89ac75
[email:Entity\User:private] => [email protected]
[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] => 
) ,

this を試しましたが、私のrequiremnetによると、ユーザーdoctrine_queryを使いたくありません。ありがとう。

15
Manoj Solanki

このようなものを試すことができます、

    $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);

別の方法、

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

上記は配列を返しますが、doctrineオブジェクトを含みます。配列を返す最良の方法はdoctrineクエリを使用することです。

お役に立てれば。乾杯!

19
Anjana Silva

注:エンティティの配列表現が必要な理由が、AJAX応答のためにJSONに変換することである場合、お勧めしますこのQ&Aの確認: Symfony 2.0でDoctrineエンティティをJSONにエンコードする方法AJAX application? 。私は、私の答えに似た組み込みのJsonSerializableインターフェースの使用について特に気に入っています。


Doctrineはエンティティを連想配列に変換する方法を提供しないため、自分で行う必要があります。 1つの簡単な方法は、エンティティの配列表現を返す関数を公開する基本クラスを作成することです。これは、基本クラスの関数呼び出しで _get_object_vars_ を呼び出すことで実現できます。この関数は、渡されたオブジェクトのaccessibleプロパティを取得し、それらを連想配列として返します。次に、配列に変換するエンティティを作成するたびに、この基本クラスを拡張する必要があります。

非常に簡単な例を次に示します。

_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 )
_

注:基本クラスがget_object_vars()を使用してエンティティにアクセスできるように、エンティティのプロパティを保護する必要があります


何らかの理由で基本クラスから拡張できない場合(おそらく既に基本クラスを拡張しているため)、少なくとも interface を作成し、エンティティがインターフェイスを実装していることを確認できます。次に、各エンティティ内にtoArray関数を実装する必要があります。

例:

_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 )
_
6
Kodos Johnson

私はSymfonyを初めて使用しますが、動作する(しかし奇妙な)方法がいくつかあります。

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

1
antongorodezkiy

数ヶ月前にリポジトリで再帰関数を作成しましたが、完全ではありません(createdByフィールドとupdatedByフィールドがある場合、$ aClassNamesDoneによる再帰に対する単純な保護のため、1人のユーザーの値のみを取得します)。しかし、それは役立つかもしれません:

    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;
}
1
Fazhom Arnaud

単純にこれを使用できます

$demo=array($demo);
0
kishan

単一の値にアクセスする必要がある場合は、これも実行できます...

「personType」がオブジェクトであり、関係の値が必要な場合...

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