Come catturare qualsiasi metodo chiamata sull'oggetto in PHP?
-
15-09-2020 - |
Domanda
Sto cercando di capire come catturare qualsiasi metodo chiamato su un oggetto in PHP.So della funzione magica __call
, ma viene attivato solo per i metodi che non esistono sull'oggetto chiamato.
Ad esempio ho qualcosa del genere:
class Foo
{
public function bar()
{
echo 'foobar';
}
public function override($method_name,$method_args)
{
echo 'Calling method ',$method_name,'<br />';
$this->$method_name($method_args); //dirty, but working
}
}
.
E quando lo faccio:
$foo = new Foo();
$foo->bar();
.
Voglio questa uscita:
Calling method bar
foobar
.
Invece di questo:
foobar
.
C'è un modo come farlo?Aiuto per favore :)
Soluzione
Prendendo la tua implementazione originale Foo
è possibile avvolgere un decorator
intorno ad esso simile a questo:
class Foo
{
public function bar() {
echo 'foobar';
}
}
class Decorator
{
protected $foo;
public function __construct(Foo $foo) {
$this->foo = $foo;
}
public function __call($method_name, $args) {
echo 'Calling method ',$method_name,'<br />';
return call_user_func_array(array($this->foo, $method_name), $args);
}
}
$foo = new Decorator(new Foo());
$foo->bar();
. Altri suggerimenti
È possibile avvolgere un oggetto attorno all'oggetto, intercettare tutte le chiamate, inoltrandole all'oggetto originale e restituire il risultato.
Basta memorizzare l'oggetto come variabile nella classe del wrapper e utilizzare i metodi di sovraccarico nella classe del wrapper per chiamare / impostare / ottenere / controllare l'oggetto.
$object = new AnyObject;
$object = new Wrapper($object);
$object->anyMethod();
$object->anyVar = 'test';
echo $object->anyVar;
echo $object['array form'];
.
Looping La classe del wrapper in Foreach è probabilmente più difficile.Non ha provato questo.
Se si imposta la funzione in privato, la chiamata intrappolerà qualsiasi chiamata all'esterno sarà intrappolata in __call, ma è possibile chiamarlo dall'interno
class Foo
{
private function bar()
{
echo 'foobar';
}
public function __call($method_name,$method_args)
{
echo 'Calling method ',$method_name,'<br />';
$this->$method_name(); //dirty, but working
}
}
.