Използване на EntityManager в обекти на Doctrine 2.0

Имам 2 обекта: Държава (id, име) и Mapping (id, обект, internalId, externalId). Държавата и картографирането не са свързани с асоциации (защото картографирането има редове не само за държава). Трябва да получа външен идентификатор за държава, като използвам следните условия:

  • country.id = mapping.internalId
  • mapping.object = 'country'

Така че планирам да добавя функция getExternalId() в Country

function getExternalId() {
    $em = Registry::getEntityManager();

    $mapping = $em->getRepository('Mapping')->findOneBy(array(
        'object'     => 'country',
        'internalId' => $this->getId()
    ));

    return !empty($mapping) ? $mapping->getExternalId() : false;
}

Въпроси:

  1. Добра практика ли е да използвате EntityManager вътре в обекти? Ако не, моля, обяснете как да получа външен идентификатор в моя случай?
  2. Може би е възможно да свържете Държава и Картографиране с помощта на yaml файлове?

Благодаря предварително!


person Torchello    schedule 05.11.2010    source източник


Отговори (4)


Не е добра идея да се позволи на обект на обект да разчита на мениджъра на обект. Той свързва обекта със слоя за устойчивост, което беше проблем, който Doctrine 2 конкретно се опитваше да реши. Най-големият проблем при разчитането на мениджъра на обекти е, че той прави вашия модел труден за тестване изолирано, далеч от базата данни.

Вероятно трябва да разчитате на обслужващи обекти, за да управлявате операциите, които разчитат на мениджъра на обекта.

// CountryService
public function getExternalId($country) {}

Освен това можете да създадете прокси методи на вашия модел, за да извикате сервизен обект, който е зададен външно. Сервизният обект би бил много по-лесен за подиграване по време на тестване, отколкото би бил мениджърът на обекти.

$country->setService($countryService);
$country->getExternalId();

// Country
public function getExternalId()
{
   $this->_service->getExternalId($this);
}  
person Bryan M.    schedule 05.11.2010
comment
Търся добри уроци за внедряване на услуги за доктрина. Някой знае ли добри уроци. - person user257980; 06.04.2011
comment
Обектът на услугата в този случай трябва ли да бъде вътрешен за обекта или можете да го използвате извън обекта? например. $service = нова държава\ServiceObject; $ExtId = $service-›getExternalId($country); - person calumbrodie; 24.06.2011
comment
изпълнение на услугата за доктрина: symfony.com/doc/current/book/service_container.html - person Jeffrey Nicholson Carré; 12.03.2013

Това може да не е най-добрата идея, но има лесен начин да направите това.

Класът UnitOfWork в доктрината ще хидратира всеки обект, който имплементира ObjectManagerAware с мениджъра на обекта и метаданните на класа за този обект.

Всичко, което трябва да направите, за да получите мениджъра на обекта във вашия обект, е да внедрите интерфейса, както е показано в примера по-долу:

use Doctrine\Common\Persistence\Mapping\ClassMetadata;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\Persistence\ObjectManagerAware;

/**
 * @ORM\Entity
 */
class MyEntity implements ObjectManagerAware
{
    public function injectObjectManager(ObjectManager $objectManager, ClassMetadata $classMetadata)
    {
        $this->em = $objectManager;
    }
}

Ако създадете нов обект, вместо да го правите заявки от базата данни, ще трябва да настроите мениджъра на обекти ръчно, например с метод за настройка.

person juanmf    schedule 15.07.2014

Мисля, че това, което трябва да използвате, са Entity Repositories. Те са описани подробно в документацията, макар и малко трудно да се намери информация. Ето връзка към Първи стъпки статия, която документира как човек може да създаде "хранилище" на функции за 'достъп' за вашите обекти.

Освен това ето малко псевдокод, за да започнете:

<?php
// repositories/CountryRepository.php

use Doctrine\ORM\EntityRepository;

class CountryRepository extends EntityRepository
{
    public function getExternalId()
    {
person MikeMurko    schedule 18.10.2011
comment
изглежда, че връзката е мъртва - person Gigala; 11.06.2013
comment
В този момент връзката работи. Мисля, че това е много добро решение на въпроса на ОП. - person Nicolás Ozimica; 15.11.2013

Леко авангардно допълнение към това (PHP 5.4 е в алфа 2 по време на тази публикация), което може да бъде от полза в бъдеще:

Ето някои примери за използване на черти на php 5.4 в Doctrine2; единият от които се нарича активен обект и предоставя функционалност за стил на активен запис в рамките на Доктрина 2, включително достъп до мениджъра на обекта от самия обект.

person Fost    schedule 31.10.2011