如何调用祖父素方法而不会出现E_STRICT错误?

Enr*_*que 12 php inheritance

有时我需要执行grandparent方法(也就是绕过父方法),我知道这是代码味道,但有时候我不能改变其他类(框架,库等).

在PHP中,我们可以通过以下方式实现:

call_user_func(array(get_parent_class(get_parent_class($childObject)), 'grandParentMethod'));
Run Code Online (Sandbox Code Playgroud)

问题是,如果您启用了E_STRICT错误,您将收到如下错误:

严格的标准:非静态方法GrandParent :: grandParentMethod()不应该在...中静态调用

我发现只有一个解决方案(没有删除E_STRICT),它只是添加@以抑制错误.

但这真的很难看,有人知道更好的解决方案吗?

谢谢 !PS:我无法实例化一个新对象,如:

$grandparent = get_parent_class(get_parent_class($son));
$gp= new $grandparent;
$gp->grandParentMethod
Run Code Online (Sandbox Code Playgroud)

因为我需要在$ son的上下文中调用我的祖父母方法.

Tim*_*hof 57

您可以直接通过姓名呼叫祖父母(不需要反射,也不需要call_user_func).

class Base {
    protected function getFoo() {
        return 'Base';
    }
}

class Child extends Base {
    protected function getFoo() {
        return parent::getFoo() . ' Child';
    }
}

class Grandchild extends Child {
    protected function getFoo() {
        return Base::getFoo() . ' Grandchild';
    }
}
Run Code Online (Sandbox Code Playgroud)

Base::getFoo呼叫可能看起来像一个静态调用(由于冒号::语法),然而事实并非如此.就像parent::不是静止的一样.

从类中的继承链调用方法将正确绑定$this值,将其作为常规方法调用,遵守可见性规则(例如受保护),并且不违反任何类型!

这一开始可能看起来有点奇怪,但是,这是在PHP中实现它的方法.

  • 这比接受的答案更清晰.我甚至不知道你能用PHP做到今天...谢谢@Krinkle (5认同)

Dr.*_*lle 2

您可以使用ReflectionMethod->invoke()

例子:

<?php
class Grandpa {
    protected $age = 'very old';
    public function sayMyAge() {
        return 'sayMyAge() in Grandpa should be very old. ' . 
                  'My age is: ' . $this->age;
    }
}

class Pa extends Grandpa {
    protected $age = 'less old';
    public function sayMyAge() {
        return 'sayMyAge() in Pa should be less old. ' .
                  'My age is: ' . $this->age;
    }
}

class Son extends Pa {
    protected $age = 'younger';
    public function sayMyAge() {
        return 'sayMyAge() in Son should be younger. ' .
                  'My age is: ' . $this->age;
    }
}

$son = new Son();
$reflectionMethod = new ReflectionMethod(get_parent_class(get_parent_class($son)), 
                                         'sayMyAge');
echo $reflectionMethod->invoke($son);
// returns:
// sayMyAge() in Grandpa should be very old. My age is: younger
Run Code Online (Sandbox Code Playgroud)

注意:调用的方法必须是公共的。

  • 我有同样的问题,但根据[这个官方错误报告](http://stackoverflow.com/questions/12850802/how-to-call-grandparent-method-without-getting-e-strict-error),如果上下文是正确的(我认为这意味着“来自子类”),调用 `GrandParent::method()` 将正确设置 `$this` 并允许以静态方式进行此非静态调用。 (2认同)