【问题标题】:How to catch any method call on object in PHP?如何在 PHP 中捕获对对象的任何方法调用?
【发布时间】:2011-03-15 14:12:28
【问题描述】:

我试图弄清楚如何捕获 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

有什么方法可以做到这一点吗?请帮忙:)

【问题讨论】:

    标签: php object interception


    【解决方案1】:

    采用您原来的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();
    

    【讨论】:

    • 谢谢伙计,这正是我需要的:)
    • 这种方法不起作用的一种情况是,如果您有需要 Foo 的方法,例如 someMethod(Foo $foo)
    【解决方案2】:

    您可以将对象包裹在对象周围,拦截任何调用,然后将它们转发到原始对象并返回结果。

    只需将对象作为变量存储在包装类中,并使用包装类中的重载方法来调用/设置/获取/检查对象。

    $object = new AnyObject;
    $object = new Wrapper($object);
    
    $object->anyMethod();
    $object->anyVar = 'test';
    echo $object->anyVar;
    echo $object['array form'];
    

    在 foreach 中循环包装类可能更难。没试过。

    【讨论】:

    • 你能说得更具体些吗?只是一个小例子:)
    【解决方案3】:

    如果将函数设置为 private , call 将捕获任何从外部对其的调用将被捕获在 __call 中,但您可以从内部调用它

    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
       }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-04-28
      • 2014-12-17
      • 1970-01-01
      • 1970-01-01
      • 2019-05-08
      • 2011-11-06
      • 2016-02-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多