Doctrine2 将实体导出到数组
我有 Product
实体与多对一到 Category
实体.我需要在会话中存储 Product
.首先,我尝试在 Product 上实现 Serializable
接口.我应该如何序列化我的相关 Category
实体?我还应该实现 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 代码并找到了DoctrineORMInternalHydrationObjectHydrator:hydraRowData
方法,但它受到了保护.有没有公开的 api 来做这件事?
I read doctrine2 code and find method DoctrineORMInternalHydrationObjectHydrator:hydrateRowData
but it's protected. Is there any public api for doing this?
我只是从 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'] & DoctrineORMMappingClassMetadata::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 AcmeServiceBundleServices;
use DoctrineORMEntityManager;
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'] & DoctrineORMMappingClassMetadata::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);
}
}
相关文章