Il metodo genitore ereditato da PHP non può accedere alla properties; privata del figlio

Prima di tutto: un problema abbastanza simile è stato pubblicato e in qualche modo risolto già, ma non risponde ancora al mio problema specifico. Maggiori informazioni su questo più tardi.

A parole: ho una class base che fornisce alcuni methods a tutti i childs, ma non contiene alcuna properties;. Mio figlio eredita questi methods, che dovrebbero essere usati per accedere alle properties; del bambino. Se la properties; del bambino è protected o public , tutto funziona bene, ma se la properties; del figlio è private , fallisce senza errori (non accade nulla).

Nel codice:

 class MyBaseClass { public function __set($name, $value) { if(!property_exists($this, $name)) throw new Exception("Property '$name' does not exist!"); $this->$name = $value; } } class ChildClass extends MyBaseClass { public $publicProperty; protected $protectedProperty; private $privateProperty; } $myChild = new ChildClass(); $myChild->publicProperty = 'hello world'; //works of course! $myChild->protectedProperty = 'hello world'; //works as expected $myChild->privateProperty = 'hello world'; //doesn't work? 

Il suddetto problema simile ha ottenuto la soluzione per utilizzare il metodo magico __set() per accedere alle properties; private, ma questo lo sto già facendo. Se implemento __set() all'interno del bambino, funziona ovviamente, ma l'idea è che il figlio erediti __set() dal suo genitore, ma ovviamente non può accedere al metodo privato del figlio.

È fatto apposta? Sto sbagliando qualcosa di sbagliato? o il mio approccio è solo una schifezza di design?

Background: La mia idea originale era: l'intera cosa dynamic di __set() è qualcosa che non mi piace. Di solito una properties; privata non dovrebbe mai essere accessibile dall'esterno, quindi ho implementato il lancio di methods __set- e __get nella mia ultima class base (da cui ereditano tutte le classi).

Ora voglio generare dynamicmente un'istanza da un file XML e quindi ho bisogno di accedere alle properties;. Ho fatto la regola, che each class XML- __set() bisogno di implementare il metodo magico __set() e quindi può essere creata dynamicmente. Invece di implementarlo in each class che potrebbe essere generata un giorno, ho deciso di farli ereditare da una class chiamata come class Spawnable { } che fornisce il metodo __set necessario.

Questa è la differenza tra private e protected . I methods e le properties; private non possono essere ereditati o raggiunti. Dovrai invece cambiarli in protetti.

Vedi il manuale sulla visibilità

I membri dichiarati protetti sono accessibili solo all'interno della class stessa e per classi ereditate e padre. I membri dichiarati come privati ​​possono essere raggiunti solo dalla class che definisce il membro.

Immagino che potresti modellare qualcosa usando Reflection. Ad esempio, nella tua class Spawnable:

 public function __set($name, $value) { $reflector = new ReflectionClass(get_class($this)); $prop = $reflector->getProperty($name); $prop->setAccessible(true); $prop->setValue($this, $value); } 

Non il più bello del codice, però.

Dopo aver esaminato il mio concetto, penso che sia una ctriggers idea, seguire quell'approccio. Questo è un problema generale con la mancanza di PHP di differenza tra properties; e campi. Ovviamente i campi privati non dovrebbero mai essere accessibili dall'esterno, ma solo le properties;, che sono definite dal programmatore. L'assenza di properties; automatiche (e non intendo questi methods magici __set() e __get() ) o alcune regole convenzionali per l'accesso alle properties;, rende difficile indovinare, quale convenzione di denominazione è stata usata dal programmatore quando implementava setter per campi privati ​​nella sua class.

Il concetto migliore potrebbe essere, fare affidamento sull'esistenza di setter ben denominati per each class spawnable, anche se potrebbe rompersi, se qualcuno ha contribuito al codice, che non sta implementando i setter convenzionali convenzionali previsti.

Tuttavia, molte grazie per i vostri pensieri e suggerimenti!