[英]Doctrine2 export entity to array
我有一個具有多對一到Category
實體的Product
實體。 我需要在會話中存儲Product
。 首先,我嘗試在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
我們有原始值。 現在我們需要如何通過這個數組創建對象
<?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;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.