PHP Reflection:如何知道ReflectionMethod是否被继承?

问题描述 投票:0回答:3

ReflectionMethod 文档中,我找不到任何内容来了解方法是从其父类继承还是在反射类中定义。

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

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

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

我想保留

a
c

php reflection php-5.3
3个回答
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";
}

5
投票

你可以获取你感兴趣的方法的

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
)

0
投票

我想在父方法中添加一些默认逻辑,但前提是子方法中没有重写。否则,子类将能够调用父类,然后决定下一步做什么。

TL;博士;

$refMethod = new \ReflectionMethod(get_called_class(), 'update');
if ($refMethod->class == get_class()) {
    // the parent method is called directly
}

这里是一个例子,如果子进程没有 update 方法,我们只添加成功消息:

class Parent
{
    public function update()
    {
        // save some information

        $refMethod = new \ReflectionMethod(get_called_class(), 'update');
        if ($refMethod->class == get_class()) {
            $this->addSuccess('Success!');
        }
    }
}
class ChildOverrides extends Parent
{
    public function update()
    {
        parent::update(); // use parent to save info
        $this->sendConfirmation();
        $this->addSuccess('Success, message sent! Do not show me a duplicate success message!');
    }
}
class LazyChild extends Parent
{
    // no update method - parent saves info ad shows "Success!". Nothing else happens here
}
© www.soinside.com 2019 - 2024. All rights reserved.