2013-10-01 31 views
0

假設以下情況。有類層次結構,它在方法中使用各種參數列表,可以爲每個後代類進行擴展。使用各種參數列表從子方法調用父方法

<?php 
header('Content-Type: text/plain; charset=utf-8'); 

class A { 
    public function __invoke(){ 
     $arguments = implode(', ', func_get_args()); 

     echo __METHOD__, ' arguments: ', $arguments, PHP_EOL; 
    } 
} 

class B extends A { 
    public function __invoke(){ 
     //    ... some actions ... 
     // call to parent method with current argument list 
     //    ... some actions ... 
    } 
} 
?> 

如果該類hierarhy用__invoke()方法的固定參數來實現的話,我可能會使用類似parent::__invoke($a, $b, $c, $etc);達到我的目的。但是,不幸的是,AB這兩個類都有一些功能,它依賴於各種參數列表。

現在的問題:我怎麼能說parent::__invoke()B::__invoke(),並通過它的參數列表?

而且,是的,我會讓它更加複雜:我不能依賴父類的實際名稱,因爲鏈可能會進一步擴展。

個人識別碼:我只是想在某個地方提一下,因爲這件事幾乎救了我今天的生活。

回答

0

有兩種實現方式,其中一種對我來說很明顯:使用Reflection

  1. A類創建ReflectionClass;

  2. ReflectionClass::getParentClass()方法得到最近父母的反射;

  3. 獲取__invoke()方法反映父類的ReflectionClass::getMethod()方法;

  4. 使用ReflectionMethod::invokeArgs()方法調用父方法,使用func_get_args()函數傳遞當前參數列表。

不過,我在想,它可能是一個矯枉過正(!)使用此功能來進行單個函數調用。所以我認爲是另一種方式:舊的威猛call_user_func_array()函數與get_parent_class()函數

  1. 獲取父類與get_parent_class()函數;

  2. 獲取當前方法名稱(我正在考慮使用__METHOD__常量,但它總是顯示一個類的前綴,其中方法聲明)與__FUNCTION__常量;

  3. 使用方法映射調用call_user_func_array()並將func_get_args()作爲第二個參數。


解決方案:

<?php 
header('Content-Type: text/plain; charset=utf-8'); 

class A { 
    public function __invoke(){ 
     $arguments = implode(', ', func_get_args()); 

     echo __METHOD__, ' arguments: ', $arguments, PHP_EOL; 
    } 
} 

class B extends A { 
    public function __invoke(){ 
     echo __METHOD__, ' actions', PHP_EOL; 

     $method = array(get_parent_class($this), __FUNCTION__); 
     $result = call_user_func_array($method, func_get_args()); 

     echo __METHOD__, ' actions', PHP_EOL; 
    } 
} 

$test = new B(); 

$test(1, 2, 3); 
?> 

結果:

B::__invoke actions 
A::__invoke arguments: 1, 2, 3 
B::__invoke actions