2012-12-11 16 views
25

ho una classe astratta genitore Mongo_Document (da mongodb-php-odm) e una classe ereditata Model_ActionPlan. Mongo_Document dispone di metodi __isset e __get magici che interagiscono con una matrice all'interno della classe Mongo_Document.PHP classe bambino lavora __isset magia, ma __get non

Sto cercando di utilizzare il seguente codice (frammento all'interno di un metodo di Model_ActionPlan): (. Si noti che close_type è garantito per essere impostata se status == 'closed')

if (isset($this->status)) 
{ 
    if (($this->status === "closed") AND ($this->close_type != "failure")) 
    { 
     return; 
    } 
} 

I isset chiamata restituisce true e quindi l'esecuzione procede alla successiva dichiarazione. Lì, ricevo il seguente errore:

Undefined property: Model_ActionPlan::$status 

Tuttavia, se sostituisco $this->status con parent::__get('status'), questo codice funziona come previsto. Si noti che in ogni altro nel programma, sono in grado di utilizzare:

$ap = new Model_ActionPlan($plan_id); 
echo $ap->status; 
// Prints 'closed' (or 'active') as expected 

E 'solo qui, all'interno della classe stessa, che questo non funziona.

Mi sono guardato intorno e non riesco a trovare da nessuna parte che dice che i metodi magici non possono essere chiamati nella classe bambino. Potrei usare la chiamata , ma penso che sia probabilmente il modo sbagliato per farlo. Qualcuno sa se esiste un modo giusto/migliore per farlo?

Aggiornato # 1 2012/12/16: il codice completo della classe padre è here on Github.

Aggiornato # 2 2012/12/18: Per le persone che hanno chiesto di dove o se è impostato correttamente, la risposta è che, dal momento chiamando parent::__get('status')fa lavoro, il problema non è, ovviamente, che la variabile non viene impostato. Il __get() riceve i dati da una variabile privata di instace denominata _object. Se I var_dump($this), vedo che $this->_object['status']corrisponde a uguale al valore "chiuso" previsto.

Aggiornamento # 3: Il codice della classe bambino è disponibile a https://gist.github.com/4332062. La parte importante inizia on line 69.


ho visto this similar question ma che si sta utilizzando il metodo magia di un genitore per ottenere le proprietà del bambino e il mio problema sta usando getter del genitore per ottenere le proprietà del genitore.

+0

Quale versione di PHP sei? Questo non dovrebbe accadere. –

+0

Sto usando '5.4.8-NTS-VC9 (Windows FastCGI)' sul mio computer locale e '5.3.10-1ubuntu3.4' sul mio server di test. Il problema si verifica su entrambi. –

+0

Ho provato a riprodurre il problema creando una classe base con metodi magici e quindi estendendolo, ma non sembra che questo mostri il problema che stai riscontrando. –

risposta

3

La funzione __get nel genitore è un po 'complessa, quindi non ho pienamente capito se il seguente potrebbe accadere o no.Se la tua funzione __get, una volta chiamata, sta in qualche modo innescando un'altra chiamata in sé (forse con alcune chiamate intermedie ad altre funzioni in pila), questo è esattamente ciò che accadrebbe.

Vedere http://php.net/manual/en/language.oop5.overloading.php#55486, che mostra lo stesso identico tipo di errore registrato quando il getter attiva una chiamata a se stesso. In questo caso, è abbastanza facile da individuare, ma con un grafico delle chiamate più complicato di qualcosa come func() a __get() a funcB() a funcC() a __get(), non sarebbe facile da individuare.

+0

Sai, potresti avere qualcosa lì. Dovrò controllare se è quello che sta succedendo.Non penso che il '__get' si chiami da solo, ma potrebbe essere che qualche altro tipo di" chiamarsi "mostri lo stesso comportamento. –

+0

Purtroppo, non sono stato in grado di verificare se questo fosse corretto prima della scadenza della taglia. Mi dispiace. Tuttavia, devo dire che questa è quasi sicuramente la risposta corretta. Ho rimosso una riga di codice che potrebbe causare chiamate nidificate a __get e ha risolto il problema. –

+0

Dolce! Sono contento che abbia funzionato. – DWright

-3

Non sono sicuro se ho ragione, ma non si dovrebbe utilizzare

$this->_object['status'] 

invece di

$this->status 
+0

Questo sarebbe vero se il getter magico ottenesse solo l'elemento dell'array. Tuttavia, ci sono cose che il metodo '__get' fa prima che ottenga l'elemento dall'array. Ho bisogno di usare il metodo '--get' per farlo fare quella roba. Inoltre, penso che sia una cattiva pratica giocare con gli interni della classe genitore invece di usare il metodo di accesso appropriato se esiste un tale metodo. Se usi '$ this -> _ object' e poi l'implementazione genitore cambia, devi preoccuparti di ciò. Se usi i metodi documentati, allora non lo fai. –

+0

Probabilmente vale più un commento in quanto è più una domanda che una risposta definitiva. – Jimbo