4

[编辑] 更新了标题以更准确地反映问题

我要解决的问题是:我需要知道是否调用了一个方法parent::,虽然我可以使用debug_backtrace它,但似乎必须有更好的方法来做到这一点。

我一直在研究后期静态绑定,但也许我对它的理解还不够深入,无法找到解决方案。

有问题的方法是__call,所以我不能简单地传入一个额外的参数,因为它的错误多或少正好是两个。

试图解决这个问题的原因是父类有__call,而子类可能有也可能没有_call。如果孩子没有它,并且父母没有调度调用,那么我想抛出异常或错误。如果孩子确实有方法,那么我会返回false(不,我们没有处理这个)并让孩子_call方法继续。

到目前为止,我唯一可行的解​​决方案是将子调用parent::__call包装在 try/catch 块中,如果父进程不路由请求,则默认情况下让父进程抛出异常。

IE。

class Parent {
  public function __call( $method, $params ) {
    if( preg_match( $this->valid, $method ) {
      $this->do_stuff();
      // if child has a call method, it would skip on true
      return true;
    }
    elseif( ** CHILD HAS CALL METHOD ** ) {
      // this would let the child's _call method kick in
      return false;
    }
    else {
      throw new MethodDoesNotExistException($method);
    }
  }
}

class Child extends Parent {
  public function __call( $method, $params ) {
    if( ! parent::__call( $method, $params ) ) {
      do_stuff_here();
    }
  }
}

如果父级不处理该方法有效,则抛出异常,我只是想看看是否有更优雅的解决方案,因为对流控制使用异常似乎不太正确。但是也没有使用堆栈跟踪来找出调用者。

4

2 回答 2

4

这应该在您的父类中执行:

if (__CLASS__ != get_class($this))
于 2012-11-13T17:31:35.807 回答
1

我不完全确定这是否符合您的需求,而且从 OO 设计的角度来看,我也认为这种黑客行为非常糟糕。但是,编码是一件有趣的事情:)

<?php

class ParentClass 
  {
  public function __call( $method, $params ) 
  {
    if($method === 'one')
    {
      echo "Parent\n";
      return true;
    }
    elseif($this->shouldForwardToSubclass($method)) 
      {
        return false;
      }
    else 
    {
      throw new Exception("No method");
    }
  }

   protected function shouldForwardToSubclass($methodName)
   {
      $myClass = get_class($this);
      if (__CLASS__ != $myClass)
      {
        $classObject = new ReflectionClass($myClass);
        $methodObject = $classObject->getMethod('__call');
        $declaringClassName = $methodObject->getDeclaringClass()->getName();
        return $myClass == $declaringClassName;
      }
      else 
          {
            return false;
          }
}

}

class ChildClass1 extends ParentClass {
  public function __call( $method, $params ) {
    if( ! parent::__call( $method, $params ) ) 
    {
      echo "Child handle!\n";
    }
  }
}

class ChildClass2 extends ParentClass {
}

后来做:

$c = new ChildClass1();
$c->one();
$c->foo();

$c = new ChildClass2();
$c->foo();

会产生:

Parent
Child handle!
PHP Fatal error:  Uncaught exception 'Exception' with message 'No method' in /home/andres/workspace/Playground/test.php:18
Stack trace:
#0 /home/andres/workspace/Playground/test.php(58): ParentClass->__call('foo', Array)
#1 /home/andres/workspace/Playground/test.php(58): ChildClass2->foo()
#2 {main}

高温高压

于 2012-11-13T20:02:08.193 回答