Un __get sovraccarico deve gestire tutte le variabili membro?
-
23-08-2019 - |
Domanda
Sto creando una funzione __get() per una classe per controllare l'accesso alle mie variabili membro private.Devo progettare la funzione per gestire tutte le possibili letture dei valori dei membri o non posso scriverla per i membri pubblici?Inoltre, presumo che le classi che ereditano questa classe utilizzeranno la mia funzione __get() per accedere ai membri privati.
class ClassA{
private $collection = array();
public $value;
function __get($item){
return $collection[$item];
}
Soluzione
No, non lo fai.
class A {
public $foo = 'bar';
private $private = array();
public function __get($key) {
echo 'Called __get() at line #' ,__LINE__, ' with key {', $key ,'}',"\n";
return $this->private[$key];
}
public function __set($key, $val) {
$this->private[$key] = $val;
}
}
$a = new A();
var_dump($a->foo);
$a->bar = 'baz';
var_dump($a->bar);
E sì, lo farà:
class B extends A { private $private = array(); }
$b = new B();
var_dump($b->bar);
Altri suggerimenti
Bene, il tuo codice fallirebbe su elementi privati non impostati nel tuo array.Ma ancora una volta, puoi usarlo come un modo per gestire ciò che è dentro e fuori dal tuo array, in quanto tale;
function __get($item){
if ( isset ( $collection[$item] ) )
return $collection[$item];
else {
try {
return $this->$item ; // Dynamically try public values
} catch (Exception $e) {
$collection[$item] = 0 ; // Make it exist
}
}
}
Le classi che ereditano le tue chiamate utilizzeranno questo __get(), ma possono essere sovrascritte, quindi usa parent::__construct() in modo esplicito.Si noti inoltre che questi non possono essere statici. Ulteriori letture.
Prima di tutto PHP cerca nome della proprietà nella definizione di classe e cerca di tornare il suo valore. Se non c'è alcuna proprietà - PHP tenta di chiamare __get ($ var) e qui si può tornare tutto quello che vuoi. Si tratta di un comportamento poco di confusione per coloro, che conoscono Java-like getter / setter in cui bisogna definirli per ogni membro della classe che si desidera accedere.
Quando è comodo da usare Java-like getter / setter - si potrebbe scrivere qualcosa di simile a questo:
public function __set($var, $value)
{
if (method_exists($this, $method = "_set_" . $var))
{
call_user_func(array($this, $method), $value);
}
}
public function __get($var)
{
if (method_exists($this, $method = "_get_" . $var))
{
return call_user_func(array($this, $method), $value);
}
}
e quindi utilizzare questo codice definendo getter personalizzati / setter
protected function _get_myValue()
{
return $this->_myValue;
}
protected function _set_myValue($value)
{
$this->_myValue = $value;
}
e l'accesso a metodi definiti in questo modo:
$obj->myValue = 'Hello world!';