PHP:在子类中包装类的所有函数

mtb*_*ave 10 php inheritance aop overriding metaprogramming

使用PHP库类,我想将它的所有公共函数包装在一个子类中......有些内容如下:

class BaseClass
{
   function do_something()
   {
        some;
        stuff;
   }

   function do_something_else()
   {
        other;
        stuff;
   }

   /*
    * 20-or-so other functions here!
    */
}

class SubClass extends BaseClass
{
   function magicalOverrideEveryone()
   {
        stuff-to-do-before;        // i.e. Display header
        call_original_function();  // i.e. Display otherwise-undecorated content
        stuff-to-do-after;         // i.e. Display footer
   }
}
Run Code Online (Sandbox Code Playgroud)

如果有一个[有点优雅/干净]的方法在一个地方完成它,我宁愿不要用相同的包装代码覆盖每个超类方法.

这可能吗?我怀疑我在这里进行元编程,甚至不知道PHP是否提供了这样的野兽,但我想问...

mea*_*gar 20

您可以使用魔术方法和不直接从基类继承的通用"代理"类来轻松完成此操作.__call

这是一个代理类的(近)完整实现,它包装你传递它的任何对象.它将在每个方法调用周围调用一些"之前"和"之后"代码.

class MyProxy {
  function __construct($object) {
    $this->object = $object;
  }

  function __call($method, $args) {
    // Run before code here

    // Invoke original method on our proxied object
    call_user_func_array(array($this->object, $method), $args);

    // Run after code here
  }
}


$base = new BaseClass();
$proxy = new MyProxy($base);

$proxy->doSomething(); // invoke $base->doSomething();
Run Code Online (Sandbox Code Playgroud)

您当然希望添加一些错误处理,例如询问代理对象是否响应给定方法,如果不响应则__call引发错误.您甚至可以将Proxy类设计为其他代理的基类.子代理类可以实现beforeafter方法.

缺点是你的"子类"不再实现BaseClass,这意味着如果你正在使用类型提示并且想要求只将类型的对象BaseClass传递给函数,这种方法将失败.