Я пытаюсь понять, как поймать любой метод, вызываемый объектом в PHP. Я знаю о волшебной функции __call
, но она срабатывает только для методов, которые не существуют на вызываемом объекте.
Например, у меня есть что-то вроде этого:
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 } }
И когда я это делаю:
$foo = new Foo(); $foo->bar();
Я хочу этот вывод:
Calling method bar foobar
вместо этого:
foobar
Есть ли способ, как это сделать? Помоги пожалуйста 🙂
Принимая вашу оригинальную реализацию Foo
вы можете обернуть вокруг нее decorator
следующим образом:
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();
Вы можете обернуть объект вокруг объекта, перехватить любые вызовы, затем перенаправить их на исходный объект и вернуть результат.
Просто сохраните объект как переменную в вашем классе-оболочке и используйте методы перегрузки в вашем классе-оболочке для вызова / установки / получения / проверки объекта.
$object = new AnyObject; $object = new Wrapper($object); $object->anyMethod(); $object->anyVar = 'test'; echo $object->anyVar; echo $object['array form'];
Цикл класса оболочки в foreach, вероятно, сложнее. Хавент попробовал это.