Doctrine2 экспортирует объект в массив

У меня есть объект Product со многими-к-одному для Category . Мне нужно хранить Product в сеансе. Прежде всего, я пытаюсь реализовать интерфейс \Serializable для продукта. Как я должен сериализовать свой связанный объект Category ? Должен ли я также реализовать интерфейс \Serializable ?

Я читал, что сериализация в доктрине – очень больная операция, и я думаю об этом:

Можем ли мы получить необработанные значения от объекта? Именно эти данные хранятся в базе данных. Если мы сможем получить эти значения, мы можем сохранить его в любом месте и воссоздать объект!

Я прочитал код doctrine2 и нашел метод Doctrine\ORM\Internal\Hydration\ObjectHydrator:hydrateRowData но он защищен. Есть ли какие-либо публичные api для этого?

Обновить:

Я просто копирую пакет и интегрирую некоторый код из BasicEntityPersister, и, похоже, он работает.

  $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 у нас есть исходные значения. Теперь нам нужен способ создания объекта по этому массиву

Solutions Collecting From Web of "Doctrine2 экспортирует объект в массив"

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

У меня была та же проблема, я тоже хотел иметь связанные данные в массиве. Поэтому я придумал следующее:

 $serializer = new Serializer($this->em); // Pass the EntityManager object $array = $serializer->serialize($message); // Returns the array (with associations!) 

Источник:

 <?php /** * Class Serializer * * @author Steffen Brem */ class Serializer { /** * @var Doctrine\ORM\EntityManager */ private $_em; /** * Constructor * * @param \Doctrine\ORM\EntityManager $em */ public function __construct(\Doctrine\ORM\EntityManager $em) { $this->_em = $em; } /** * Serialize entity to array * * @param $entityObject * @return array */ public function serialize($entityObject) { $data = array(); $className = get_class($entityObject); $metaData = $this->_em->getClassMetadata($className); foreach ($metaData->fieldMappings as $field => $mapping) { $method = "get" . ucfirst($field); $data[$field] = call_user_func(array($entityObject, $method)); } foreach ($metaData->associationMappings as $field => $mapping) { // Sort of entity object $object = $metaData->reflFields[$field]->getValue($entityObject); $data[$field] = $this->serialize($object); } return $data; } }