Вы получаете уникальный экземпляр сущности из Доктрины. Если вы запросите его два раза, вы всегда получите один и тот же объект.
Как следствие, если ваша сущность сначала загружается лениво (например, через @ManyToOne где-нибудь), этот экземпляр сущности будет прокси.
Пример:
У вас есть объект User, имеющий двунаправленный @OneToOne
в объекте Config ...
Дело 1
Вы запрашиваете у вашего пользователя:
- вы получаете настоящий экземпляр пользователя
- $ user-> config будет содержать прокси
Если позже вы запросите ту же сущность Config в любой части вашего приложения, вы получите этот прокси.
Дело 2
Вы запрашиваете свою конфигурацию, и ваш пользователь никогда не был импортирован:
- вы получаете реальный экземпляр Config
- $ config-> user будет содержать прокси
Если позже вы запросите одну и ту же сущность пользователя в любой части вашего приложения, вы получите этот прокси.
В общем, повторный запрос для той же сущности все равно будет превращаться в прокси (который в любом случае является экземпляром вашего пользователя, потому что сгенерированный прокси происходит от него).
Если вам действительно нужен второй экземпляр вашей сущности, который является real
(если некоторая логика вашего приложения имеет get_class
, который вы не можете заменить на instanceof
, например, ), вы можете попробовать поиграть с $em->detach()
, но это будет кошмар (и, следовательно, ваше приложение может вести себя даже с большей магией, чем Doctrine уже приносит).
Решением (исходя из моей темной стороны, я полагаю) может быть воссоздание неуправляемой сущности вручную.
public function getRealEntity($proxy)
{
if ($proxy instanceof Doctrine\ORM\Proxy\Proxy) {
$metadata = $this->getManager()->getMetadataFactory()->getMetadataFor(get_class($proxy));
$class = $metadata->getName();
$entity = new $class();
$reflectionSourceClass = new \ReflectionClass($proxy);
$reflectionTargetClass = new \ReflectionClass($entity);
foreach ($metadata->getFieldNames() as $fieldName) {
$reflectionPropertySource = $reflectionSourceClass->getProperty($fieldName);
$reflectionPropertySource->setAccessible(true);
$reflectionPropertyTarget = $reflectionTargetClass->getProperty($fieldName);
$reflectionPropertyTarget->setAccessible(true);
$reflectionPropertyTarget->setValue($entity, $reflectionPropertySource->getValue($proxy));
}
return $entity;
}
return $proxy;
}