Могу ли я получить доступ к поля дискриминатора из php в doctrine2?

У меня есть сущность, которая определяет наследование следующим образом:

* @DiscriminatorColumn(name="type", type="string") * @DiscriminatorMap({"text" = "TextAttribute", "boolean" = "BooleanAttribute", "numeric" = "NumericAttribute", "date" = "DateAttribute"}) 

Мне интересно, возможно ли получить getter для типа поля? Я знаю, что могу использовать instanceof (и в большинстве случаев это то, что я делаю), но есть несколько сценариев, в которых $ item-> getType () сделает мою жизнь намного проще.

Related of "Могу ли я получить доступ к поля дискриминатора из php в doctrine2?"

Расширяя сказанное Beberlei, вы можете объявить некоторые константы в классе Attribute и абстрактную getType() . Затем перегрузите его в каждом производном классе атрибутов.

Что-то вроде:

 abstract class Attribute { const TYPE_BOOL = 0; const TYPE_INT = 1; ... abstract public function getType(); } class BooleanAttribute extends Attribute { public function getType() { return parent::TYPE_BOOL; } } 

Вот как я буду делать.

Во-первых, вы создали AttributeInterface , чтобы убедиться, что все будущие новые типы атрибутов будут реализовывать метод потребности:

 interface AttributeInterface { /** * Return the attribute type */ public function getType(); } 

Затем вы создаете абстрактный класс AttributeInterface реализующий интерфейс AttributeInterface .

Используйте константы в вызове @DiscrimatorMap для некоторой согласованности

 /** * Attribute * ... * @DiscriminatorColumn(name="type", type="string") * @DiscriminatorMap({Attribute::TYPE_TEXT = "TextAttribute", Attribute::TYPE_BOOLEAN = "BooleanAttribute", Attribute::TYPE_NUMERIC = "NumericAttribute", Attribute::TYPE_DATE = "DateAttribute"}) */ abstract class Attribute implements AttributeInterface { const TYPE_TEXT = 'text'; const TYPE_BOOLEAN = 'boolean'; const TYPE_NUMERIC = 'numeric'; const TYPE_DATE = 'date'; } 

Наконец, вы создаете все необходимые классы, расширяя класс Attribute и реализуя метод getType()

 /** * TextAttribute * * @ORM\Entity */ class TextAttribute extends Attribute { public function getType() { return $this::TYPE_TEXT; } } /** * BooleanAttribute * * @ORM\Entity */ class BooleanAttribute extends Attribute { public function getType() { return $this::TYPE_BOOLEAN; } } /** * NumericAttribute * * @ORM\Entity */ class NumericAttribute extends Attribute { public function getType() { return $this::TYPE_NUMERIC; } } /** * DateAttribute * * @ORM\Entity */ class DateAttribute extends Attribute { public function getType() { return $this::TYPE_DATE; } } // And so on... 

Это возможно либо с помощью EntityManager, либо с помощью DocumentManager.

 $documentManager->getClassMetadata(get_class($entity))->discriminatorValue; 

Мой подход состоит в том, чтобы просто получить доступ к его значению с помощью доктрины метаданных

 $cmf = $em->getMetadataFactory(); $meta = $cmf->getMetadataFor($class); $meta->discriminatorValue 

даст вам значение, так как метод

 public static function get_type() { //...get the $em instance $cmf = $em->getMetadataFactory(); $meta = $cmf->getMetadataFor(__CLASS__); return $meta->discriminatorValue; } 

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

Нет, это невозможно, но вы можете сделать что-то вроде: get_class ($ object) == TYPE_CONST

В PHP 5.3 есть более легкий способ:

 abstract Parent { const TYPE = 'Parent'; public static function get_type() { $c = get_called_class(); return $c::TYPE; } } class Child_1 extends Parent { const TYPE = 'Child Type #1'; //..whatever } class Child_2 extends Parent { const TYPE = 'Child Type #2'; //...whatever } 

Используйте что-то вроде этого, если хотите, как и я, избегать использования константы:

 public function getType() { $type = explode('\\', get_class($this)); return end($type); } 

Еще один более легкий способ, чем перегрузить метод в каждом дочернем элементе с помощью собственного symfony:

 public function getType() { return (new \ReflectionClass($this))->getShortName(); } 

Он может не возвращать точно имя дискриминатора в зависимости от вашего объявления карты дискриминатора, но он вернет имя дочернего объекта (имя класса), которое является отличным способом назвать и отличить разные сущности

Без необходимости определять что-либо в подклассах.