2013-03-11 17 views
5

Io lavoro con zf2.1.3 e doctrine 2. Stavo cercando di idratare le informazioni sulla mia classe e mi rendo conto che lo DoctrineModule\Stdlib\Hydrator\DoctrineObject non funziona con i campi che hanno sottolineato su di esso, come cat_id.Doctrine 2 Hydrator - campi con sottolineatura

Ecco un esempio:

/* namespace Application\Entity; */ 

class Foo 
{ 
    private $cat_id; 
    private $cat_name; 

    public function getCatId() 
    { 
     return $this->cat_id; 
    } 

    public function setCatName($name) 
    { 
     $this->cat_name = $name; 
     return $this; 
    } 

    public function getCatName() 
    { 
     return $this->cat_nome; 
    } 
} 

class Bar 
{ 
    private $id; 
    private $name; 

    public function getId() 
    { 
     return $this->id; 
    } 

    public function setName($name) 
    { 
     $this->name = $name; 
     return $this; 
    } 

    public function getName() 
    { 
     return $this->nome; 
    } 
} 

/* namespace Application\Controller; */ 

use \DoctrineModule\Stdlib\Hydrator\DoctrineObject; 
public function indexAction() 
{ 
    $hydrator = new DoctrineObject($this->getEntityManager(), 'Application\Entity\Foo'); 
    $foo = $hydrator->hydrate(array('cat_name' => 'Frank Moraes'), new Foo()); 
    \Zend\Debug\Debug::dump($foo, 'Foo Hydrator'); 

    $hydrator = new DoctrineObject($this->getEntityManager(), 'Application\Entity\Bar'); 
    $bar = $hydrator->hydrate(array('name' => 'Frank Moraes'), new Bar()); 
    \Zend\Debug\Debug::dump($inscrit, 'Bar Hydrator'); 
} 

Questo codice restituisce quanto segue:

Foo Hydrator 
object(Application\Entity\Foo) 
    private 'cat_id' => null 
    private 'cat_name' => null 

Bar Hydrator 
object(Application\Entity\Foo) 
    private 'id' => null 
    private 'name' => 'Frank Moraes' 

Quindi la mia domanda è: perché Dottrina Hydrator non funziona con i campi che hanno sottolineato in esso? Come posso fare questo lavoro?

Grazie!

cura

Scusate per il lungo tempo con nessuna risposta. A non ho accesso a SO sul mio lavoro!

ho provato la seguente:

$hydrator = new DoctrineObject($this->getEntityManager(), 'Application\Entity\Foo', false); 

Per l'esempio che ho postato qui, questo parametro false funziona benissimo.

Ma, non funziona quando lego la classe su un modulo!

Qualcuno ha un indizio?

+0

io avrei posto questa domanda sul gruppo di utenti di Google Dottrina. –

+0

Questo perché l'inflector di default non gestisce i caratteri di sottolineatura. Devi modificarlo da solo o postare un problema sul tracker dei problemi del modulo doctrine su https://github.com/doctrine/DoctrineModule/issues Posso dirti ora che non ho tempo di guardare in questo momento però. – Ocramius

+0

Ho pubblicato il problema su https://github.com/doctrine/DoctrineModule/issues/190 – vinigarcia87

risposta

9

diversi mesi dopo questo è stato chiesto, ma io sono stato il controllo del codice sorgente del DoctrineObject idratante solo ora, e credo che questo è quello che sta succedendo:

Per impostazione predefinita, a meno che non si costruisce il DoctrineObject hydrator con il flag byValue come false, l'idratatore funzionerà nella modalità byValue. Ciò significa che tenta di costruire i nomi dei metodi getter e setter dai valori che stai cercando di idratare, e il modo in cui lo fa chiamando ucfirst sul nome del campo e prependi get/set a quello.

Quindi, ad esempio, si dispone di cat_name, quindi proverà il metodo getter getCat_name che è chiaramente errato.

Hai 4 scelte, quindi:

  • A:camelCase vostri nomi delle variabili
  • B: Impostare byValue su false (in modo che tenta di accedere direttamente alle variabili) [anche se io pensi che potresti dover rendere pubbliche le variabili in quel caso ... Non sono sicuro di come la visibilità influirà, poiché non l'ho provato prima)
  • C: Utilizzare un diverso idratazione Strategy o
  • D: Basta avere nomi getter e setter strani come getCat_name (per favore non farlo).
+2

Grazie per aver postato questo! L'ho risolto cambiando i nomi delle variabili in camelCase. Buono a sapersi il motivo di questo problema! – vinigarcia87

+0

Nessun problema! Lieto che aiuti. –

+0

Per l'opzione ** B ** non è necessario impostare le proprietà su pubblico perché verrà [interrompe il caricamento pigro] (http://stackoverflow.com/questions/4090609/how-can-public-fields-break-lazy- loading-in-dottrina-2). Se vuoi accedere alle tue proprietà senza getter e setter, devi implementare [magic '__get' e' __set'] (http://php.net/manual/en/language.oop5.magic.php) – Wilt

0

Veloce e sporco ...

foreach ($form as $key => $value) { 
     while ($pos = strrpos($key,'_')) {         
      $key = substr_replace($key, '', $pos, 1); 
      $capitalized = strtoupper($key[$pos]); 
      $key[$pos] = $capitalized;         
     } 
     $data[$key] = $value; 
    } 
0

È ancora possibile utilizzare questo trucco:

/** @ORM\Column(name="column_name", type="string") */ 
protected $columnName; 

function get(...); 
function set($columnName){$this->columnName = $columnName} 

Speranza aiuta