[edit]更新标题以更准确地反映问题
我想解决的问题是:我需要知道是否通过parent::
调用了一个方法,而我可以使用debug_backtrace
似乎必须有更好的方法来执行此操作
我一直在研究后期的静态绑定,但也许我不太了解它,以便深入了解解决方案。
有问题的方法是__call
所以我不能简单地传递一个额外的参数作为它的错误,或者更多或更少的两个。
尝试解决此问题的原因是父类有__call
,但孩子可能有_call
,也可能没有false
。如果孩子没有它,并且父母没有发出呼叫,那么我想抛出异常或错误。如果孩子确实有这个方法,那么我将返回_call
(不,我们没有处理这个)并让孩子parent::__call
方法继续。
到目前为止,我唯一可行的解决方案是将子句调用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();
}
}
}
包装在try / catch块中,如果父路由器不路由请求,则默认会抛出异常。
即
{{1}}
如果父进程没有处理该方法,抛出异常虽然有效,但我只是想看看是否有更优雅的解决方案,因为使用flow-controll的异常似乎不太合适。但是也没有使用堆栈跟踪来找出调用者。
答案 0 :(得分:4)
这应该在您的父类中执行:
if (__CLASS__ != get_class($this))
答案 1 :(得分: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}
HTH