2012-02-27 22 views
3

ReflectionMethod documentation中,我找不到任何知道它的方法是從它的父類繼承還是在反射類中定義的。我使用ReflectionClass::getMethods()。我想知道每種方法是否已經在類中定義了它,或者它是否已經在父類中定義。最後,我只想保留當前類中定義的方法。PHP反射:如何知道ReflectionMethod是否被繼承?

class Foo { 
    function a() {} 
    function b() {} 
} 

class Bar extends Foo { 
    function a() {} 
    function c() {} 
} 

我想保持ac

+3

什麼是你想達到什麼目的? – 2012-02-27 20:37:31

+0

我想知道一個方法是從父類繼承還是在「反映」類中定義(即沒有繼承)。你不明白的是什麼? – 2012-02-27 20:43:58

+1

@Matthieu:你必須要這樣做 - 有一個原因 - 你的最終目標是什麼?我不太熟悉Reflection API,但是你甚至能夠訪問只在父類中定義的方法嗎? – 2012-02-27 20:45:00

回答

5

您應該可以致電ReflectionMethod::getDeclaringClass()獲取聲明該方法的類。然後致電ReflectionClass::getParentClass()獲取父類。最後,撥打ReflectionClass::hasMethod()的電話會告訴您該方法是否在父類中聲明。

例子:

<?php 
class Foo { 
    function abc() {} 
} 

class Bar extends Foo { 
    function abc() {} 
    function def() {} 
} 


$bar = new Bar(); 

$meth = new ReflectionMethod($bar, "abc"); 
$cls = $meth->getDeclaringClass(); 
$prnt = $cls->getParentClass(); 

if ($cls->hasMethod($meth->name)) { 
    echo "Method {$meth->name} in Bar\n"; 
} 
if ($prnt->hasMethod($meth->name)) { 
    echo "Method {$meth->name} in Foo\n"; 
} 

$meth = new ReflectionMethod($bar, "def"); 
$cls = $meth->getDeclaringClass(); 
$prnt = $cls->getParentClass(); 

if ($cls->hasMethod($meth->name)) { 
    echo "Method {$meth->name} in Bar\n"; 
} 
if ($prnt->hasMethod($meth->name)) { 
    echo "Method {$meth->name} in Foo\n"; 
} 
+0

好的,我明白你在做什麼,但是在'abc'的情況下,我會知道它在父類中,但是我不知道它是否在'Bar'中定義(繼承或者覆蓋沒有區別)。我只想保留'Foo'的方法。 – 2012-02-27 20:51:50

+0

我更新了示例以展示如何檢查方法是否在'Bar'中。您應該能夠使用if語句的組合來獲得您正在查找的結果。 – MitMaro 2012-02-27 20:55:56

+0

這是一個很好的作品,謝謝! – 2012-02-27 21:03:12

4

你可以得到你所感興趣的方法ReflectionMethod對象,然後用getPrototype()得到父類的方法ReflectionMethod。如果該方法不覆蓋父級中的方法,則會拋出異常。

下面的示例代碼將創建一個數組,其中包含方法名稱作爲鍵以及定義用於反射類的實現的類。

class Base { 
    function basemethod() {} 
    function overridein2() {} 
    function overridein3() {} 
} 
class Base2 extends Base { 
    function overridein2() {} 
    function in2only() {} 
    function in2overridein3() {} 
} 
class Base3 extends Base2 { 
    function overridein3() {} 
    function in2overridein3() {} 
    function in3only() {} 
} 

$rc = new ReflectionClass('Base3'); 
$methods = array(); 
foreach ($rc->getMethods() as $m) { 
    try { 
     if ($m->getPrototype()) { 
      $methods[$m->name] = $m->getPrototype()->class; 
     } 
    } catch (ReflectionException $e) { 
     $methods[$m->name] = $m->class; 
    } 
} 

print_r($methods); 

這將打印:

Array 
(
    [overridein3] => Base 
    [in2overridein3] => Base2 
    [in3only] => Base3 
    [overridein2] => Base 
    [in2only] => Base2 
    [basemethod] => Base 
)