【问题标题】:PHP Reflection: How to know if a ReflectionMethod is inherited?PHP反射:如何知道ReflectionMethod是否被继承?
【发布时间】:2014-02-11 14:31:11
【问题描述】:

在ReflectionMethod documentation 中,我找不到任何可以知道方法是从其父类继承还是在反射类中定义的信息。

编辑:我使用ReflectionClass::getMethods()。我想知道每个方法是否已在被反映的类中定义,或者是否已在父类中定义。最后,我只想保留当前类中定义的方法。

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

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

我想保留a 和c。

【问题讨论】:

  • 你想要达到什么目的?
  • 我想知道一个方法是从父类继承还是在被“反射”的类中定义(即未继承)。什么是你不明白的?
  • @Matthieu:你一定想这样做是有原因的——那是什么原因(你的最终目标)?我对反射 API 不太熟悉,但是您甚至可以访问仅在父类中定义的方法吗?
  • @Madmartigan 是的,我最终得到了类的方法和父类的方法(我只想保留当前类的方法)
  • @Madmartigan 是的,我完全明白你的意思。我总是得到那些 cmets,因为我经常问奇怪的问题,人们认为我做错了(因为这里有很多问题都是这样的)......我正在尝试为 PHP 制作一个 AOP 框架,我在过程中使用反射。

标签: php reflection php-5.3


【解决方案1】:

您应该能够调用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";
}

【讨论】:

  • 好的,我知道你在做什么,但在abc 的情况下,我会知道它在父类中,但我不知道它是否在Bar 中定义(那里继承或覆盖之间没有区别)。我只想保留Foo 的方法。
  • 我更新了示例以显示如何检查方法是否在Bar 中。您应该能够使用 if 语句的组合来获得您正在寻找的结果。
  • 您也可以改用ReflectionMethod::getPrototype()。这种方法更直接一些。
【解决方案2】:

你可以获取你感兴趣的方法的ReflectionMethod对象,然后在父类中使用getPrototype()获取该方法的ReflectionMethod。如果该方法没有覆盖父类中的方法,则会抛出ReflectionClass 异常。

以下示例代码将创建一个数组,其中方法名称为键,该类为反射类定义了正在使用的实现。

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
)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-30
    • 2013-02-03
    • 1970-01-01
    • 1970-01-01
    • 2018-02-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多