Подтвердить что ты не робот

Получить объект типа Child вместо родителя из MongoDB

Я пытаюсь извлечь объект из MongoDB, но мне грозит проблема с тем, что он возвращает элемент базового типа вместо дочернего, и это вызывает проблемы, я выяснил, что он каким-то образом зависит от значения свойства.

/**
 * @MongoDB\Document(
 *     collection="zoo",
 *     repositoryClass="ZooRepository",
 * )
 */
class Zoo
{
    /**
     * @MongoDB\ReferenceMany(targetDocument="Animal", inversedBy="zoo", strategy="addToSet")
     * @var \Doctrine\Common\Collections\ArrayCollection
     */
    protected $animals;


    /**
     * @return mixed
     */
    public function getAnimals()
    {
        return $this->animals->toArray();
    }

    //Some more code

}


/**
 * @MongoDB\Document(
 *     repositoryClass="AnimalRepository",
 *     collection="animals"
 * )
 * @MongoDB\InheritanceType("SINGLE_COLLECTION")
 * @MongoDB\DiscriminatorField("discriminator")
 * @MongoDB\DiscriminatorMap({
 *     "animal"="Animal",
 *     "birds"="Bird",
 *     "mamals"="Mamals"})
 */
class Animal
{
    /**
     * @MongoDB\ReferenceMany(targetDocument="Location", mappedBy="animals", simple=true, cascade={"persist"})
     *
     * @Assert\Count(min="0", max="1")
     */
    protected $locations;
}


/**
 * @MongoDB\Document(repositoryClass="AnimalRepository")
 */
class Bird extends Animal
{

}

/**
 * @MongoDB\Document(repositoryClass="AnimalRepository")
 */
class Mamals extends Animal
{

}

Проблема заключается в следующем: когда я вызываю getAnimals() из ZooHandler, он возвращает объект типа Animal. То, что я хочу, это тип мамалей или птиц. Странная вещь, если у меня есть элемент в Animals- > location, тогда я правильно понял (Mamal/Bird), и если у него нет элемента, то я получил базовый тип.

Если я получаю список всех животных непосредственно из AnimalRepository в AnimalHandler, я получаю соответственно объекты Mamals/Bird.

Редакция: Объект зоопарка

> db.zoo.findOne()
{
    "_id" : ObjectId("5822bd23085f753b5a5a2408"),
    "name" : "Zoo 2",
    "active" : true,
    "archived" : false,
    "animals" : [
        DBRef("animals", ObjectId("556cc7adec045b1a0c8b4567"),{ "$db": "tester", "discriminator": "Test\\Bundle\\Core\\Document\\Animal" }),
        DBRef("animals", ObjectId("556cb3b0ec045bbf068b4582"),{ "$db": "tester", "discriminator": "Test\\Bundle\\Core\\Document\\Animal" })
    ]
}

Конечно, есть еще несколько свойств, которые не отображаются, так как они неактуальны.

4b9b3361

Ответ 1

Я понял, что если я сохраню объект как объект базового класса, чем он вернет объект базового класса, и поэтому в приведенном выше примере, если мне нужно получить желаемые результаты, я должен сохранить его соответствующим образом.

Ответ 2

Если я правильно понимаю вашу проблему, вам нужен встроенный PHP get_class() или get_called_class().

Примечание. сами объекты не должны забывать, к какому классу они принадлежат, даже если они возвращаются функцией/методом, которые только "знают", они возвращают некоторый экземпляр суперкласса или одного его подклассов. Поэтому вы всегда должны иметь возможность запросить, к какому классу принадлежит экземпляр, через функцию get_class($instance).