在 ReflectionMethod 文档中,我找不到任何内容来了解方法是从其父类继承还是在反射类中定义。
编辑:我使用ReflectionClass::getMethods()。我想知道每个方法是否已在所反射的类中定义,或者是否已在父类中定义。最后,我想只保留当前类中定义的方法。
class Foo {
function a() {}
function b() {}
}
class Bar extends Foo {
function a() {}
function c() {}
}
我想保留
a
和 c
。
您应该能够调用 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";
}
你可以获取你感兴趣的方法的
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
)
我想在父方法中添加一些默认逻辑,但前提是子方法中没有重写。否则,子类将能够调用父类,然后决定下一步做什么。
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
}