Posso accedere al field discriminatore da php in doctrine2?

Ho un'entity framework; che definisce l'ereditarietà come questa:

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

Mi chiedo se sia ansible avere getter per il field 'tipo'? So che posso usare instanceof (e nella maggior parte dei casi questo è quello che sto facendo) ma ci sono pochi scenari in cui $ item-> getType () renderebbe la mia vita molto più facile.

Estendendo quanto detto da beberlei, è ansible dichiarare alcune costanti nella class Attribute e una function astratta getType() . Quindi, sovraccaricarlo in each class di attributi derivata.

Qualcosa di simile a:

 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; } } 

Ecco come farei.

Innanzitutto, hai creato una AttributeInterface , per essere sicuro che tutti i futuri nuovi tipi di Attributo implementeranno il metodo della necessità:

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

Quindi si crea la class astratta Attribute implementa l'interface AttributeInterface .

Utilizzare le costanti nella chiamata @DiscrimatorMap per una certa coerenza

 /** * 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 = 'numbersc'; const TYPE_DATE = 'date'; } 

Infine, crei tutte le classi necessarie, estendendo la class Attribute e implementando il metodo 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... 

È ansible con EntityManager o utilizzando DocumentManager.

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

Il mio approccio è quello di accedere semplicemente al suo valore attraverso la doctrine dei metadati

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

ti darà il valore, quindi come metodo

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

Metto in cache i metadati in una variabile statica per each class che estende la mia entity framework; di base, ci sono anche molte altre informazioni utili …

No, non è ansible, ma puoi fare qualcosa del tipo: get_class ($ object) == TYPE_CONST

C'è un modo semplice per farlo in 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 } 

Usa qualcosa di simile se vuoi, come me, evitare l'uso di const:

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

Un altro modo per sfogliare che sovraccaricare il metodo in each bambino, con symfony nativo:

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

Potrebbe non restituire esattamente il nome del discriminatore in base alla dichiarazione della mappa discriminatore, ma restituirà il nome dell'entity framework; figlio (il nome della class) che è un ottimo modo per nominare e distinguere le diverse sottoentity framework;

Senza la necessità di definire nulla nelle sottoclassi.