2012-11-13 12 views
3

[編輯]更新標題更準確地反映問題呼叫孩子clases' __call方法,如果它存在,並拋出一個異常,如果不

我試圖解決的問題是這樣的:我需要知道如果通過parent::調用某個方法,而我可以使用debug_backtrace,則似乎必須有更好的方法來執行此操作。

我一直在尋找遲到的靜態綁定,但也許我不明白它足以揣測一個解決方案。

有問題的方法是__call所以我不能簡單地傳入一個額外的參數,因爲它的錯誤大概是兩個或更多。

試圖解決這個問題的原因是,父類有__call,但孩子可能有也可能沒有_call。如果孩子沒有,並且父母不派遣電話,那麼我想拋出異常或錯誤。如果孩子確實有方法,那麼我會返回false(不,我們沒有處理這個),並讓孩子_call方法繼續。

到目前爲止,我唯一的工作解決方案是讓子項調用parent::__call包裝在try/catch塊中,並且如果它沒有路由請求,則父項會默認引發異常。

即。

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(); 
    } 
    } 
} 

雖然拋出一個異常,如果家長不處理方法的工作,我只是想看看有沒有更好的解決方案,如使用流量控制研究例外似乎並不完全正確。但是也沒有使用堆棧跟蹤來找出調用者。

+0

那是什麼你不知道何時使用後期狀態綁定? – arkascha

回答

4

這應該在你的父類做的事:

if (__CLASS__ != get_class($this)) 
+0

這告訴我孩子類的名稱和父類的名稱,但實際上並沒有讓我確定是否有孩子'_call'方法 – Will

+0

這會得到你想要的,但我會建議OP把你的孩子課程的知識放在父類中是一種糟糕的設計方法。 –

+0

@好吧,它會回答標題中的問題。你的子類總是有一個'__call'方法,因爲它從父類繼承。你必須做很多反省才能弄清楚你的子類是否有自己的'__call'方法。這聽起來像不好的應用程序結構。家長根本不應該意識到自己的孩子。在適當的情況下,孩子會覆寫父母,沒有別的。 – deceze

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

相關問題