Doctrine2导出实体到数组 [英] Doctrine2 export entity to array

查看:103
本文介绍了Doctrine2导出实体到数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有产品实体,具有多对一到类别实体。我需要在会话中存储产品。首先我尝试在Product上实现 \Serializable 接口。我应该如何序列化我的相关的类别实体?我还应该实现 \Serializable 接口吗?

I have Product entity with many-to-one to Category entity. I need store Product in session. First of all i try to implement \Serializable interface on Product. How should i serialize my related Category entity? Should i also implement \Serializable interface?

我读过,这个序列化在教义中是非常痛苦的操作,想想这个:

I read, that serialization in doctrine is very pain operation and i think about this:

我们可以从实体获取原始值吗?正是数据存储在数据库中。如果我们可以得到这个值,我们可以将它存储在任何位置并重新创建对象!

Can we get raw values from entity? Exactly that data, which stored in database. If we can get this values, we can store it anywhere and recreate object!

我读了doctrine2代码并找到方法 Doctrine\ORM\ Internal\Hydration\ObjectHydrator:hydrateRowData 但它受到保护。有没有公​​开api这样做?

I read doctrine2 code and find method Doctrine\ORM\Internal\Hydration\ObjectHydrator:hydrateRowData but it's protected. Is there any public api for doing this?

我只是copypaste并集成一些代码从BasicEntityPersister它似乎工作。

I just copypaste and integrate some code from BasicEntityPersister and it seems to work.

    $product = $productsRepository->find($id);

    if (!$product) {
        throw $this->createNotFoundException('No product found for id ' . $id);
    }

    $uow = $em->getUnitOfWork();
    $entityPersister = $uow->getEntityPersister(get_class($product));
    $classMetadata = $entityPersister->getClassMetadata();

    $originalData = $uow->getOriginalEntityData($product);

    $result = array();
    foreach ($originalData as $field => $value) {
        if (isset($classMetadata->associationMappings[$field])) {
            $assoc = $classMetadata->associationMappings[$field];

            // Only owning side of x-1 associations can have a FK column.
            if ( ! $assoc['isOwningSide'] || ! ($assoc['type'] & \Doctrine\ORM\Mapping\ClassMetadata::TO_ONE)) {
                continue;
            }

            if ($value !== null) {
                $newValId = $uow->getEntityIdentifier($value);
            }

            $targetClass = $em->getClassMetadata($assoc['targetEntity']);
            $owningTable = $entityPersister->getOwningTable($field);

            foreach ($assoc['joinColumns'] as $joinColumn) {
                $sourceColumn = $joinColumn['name'];
                $targetColumn = $joinColumn['referencedColumnName'];

                if ($value === null) {
                    $result[$owningTable][$sourceColumn] = null;
                } else if ($targetClass->containsForeignIdentifier) {
                    $result[$owningTable][$sourceColumn] = $newValId[$targetClass->getFieldForColumn($targetColumn)];
                } else {
                    $result[$owningTable][$sourceColumn] = $newValId[$targetClass->fieldNames[$targetColumn]];
                }
            }
        } elseif (isset($classMetadata->columnNames[$field])) {
            $columnName = $classMetadata->columnNames[$field];
            $result[$entityPersister->getOwningTable($field)][$columnName] = $value;
        }
    }

    print_r($result);

$ result 中,我们有原始值。现在我们需要如何通过这个数组创建对象

In $result we have raw values. Now we need way how to create object by this array

推荐答案

<?php

namespace Acme\ServiceBundle\Services;

use Doctrine\ORM\EntityManager;

class EntitySerializer
{
    protected $em;

    public function __construct(EntityManager $em)
    {
        $this->em = $em;
    }

    public function serialize($entity)
    {
        $className = get_class($entity);

        $uow = $this->em->getUnitOfWork();
        $entityPersister = $uow->getEntityPersister($className);
        $classMetadata = $entityPersister->getClassMetadata();

        $result = array();
        foreach ($uow->getOriginalEntityData($entity) as $field => $value) {
            if (isset($classMetadata->associationMappings[$field])) {
                $assoc = $classMetadata->associationMappings[$field];

                // Only owning side of x-1 associations can have a FK column.
                if ( ! $assoc['isOwningSide'] || ! ($assoc['type'] & \Doctrine\ORM\Mapping\ClassMetadata::TO_ONE)) {
                    continue;
                }

                if ($value !== null) {
                    $newValId = $uow->getEntityIdentifier($value);
                }

                $targetClass = $this->em->getClassMetadata($assoc['targetEntity']);
                $owningTable = $entityPersister->getOwningTable($field);

                foreach ($assoc['joinColumns'] as $joinColumn) {
                    $sourceColumn = $joinColumn['name'];
                    $targetColumn = $joinColumn['referencedColumnName'];

                    if ($value === null) {
                        $result[$sourceColumn] = null;
                    } else if ($targetClass->containsForeignIdentifier) {
                        $result[$sourceColumn] = $newValId[$targetClass->getFieldForColumn($targetColumn)];
                    } else {
                        $result[$sourceColumn] = $newValId[$targetClass->fieldNames[$targetColumn]];
                    }
                }
            } elseif (isset($classMetadata->columnNames[$field])) {
                $columnName = $classMetadata->columnNames[$field];
                $result[$columnName] = $value;
            }
        }

        return array($className, $result);
    }

    public function deserialize(Array $data)
    {
        list($class, $result) = $data;

        $uow = $this->em->getUnitOfWork();
        return $uow->createEntity($class, $result);
    }
}

这篇关于Doctrine2导出实体到数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆