如何在php中调用受保护的方法?

如何在php中调用受保护的方法?,php,oop,Php,Oop,这是班级结构。我希望Observer:callme()也可以从孩子们那里调用 class Observer { protected callme() { } } class Parent extends Observer { function createChild() { $this->callme(); // this is OK return new Child ($this); } } class

这是班级结构。我希望Observer:callme()也可以从孩子们那里调用

class Observer
{
    protected callme()
    {
    }
}

class Parent extends Observer
{
    function createChild()
    {
        $this->callme(); // this is OK
        return new Child ($this);
    }
}

class Child
{
    private $this myParent;
    public function __constructor ($myParent)
    {
        $this->myParent = $myParent;
    }

    public function __destroy()
    {
        $this->myParent->callme(); // FAIL!
    }
}

那么,如何让失败发挥作用呢?(不公开,因为它仅用于“父”及其“子”内部)

受保护的
意味着您只能从同一类和子类调用该方法。你想做的是不可能的。如果您可以从任何地方调用这些方法,
protected
关键字将毫无意义


在C++中,有<代码>朋友< /Cord>关键字来实现你想要的:你可以将观察者定义为子>代码>朋友>代码(这必须由观察者完成),然后你可以从子方法中调用观察者中的所有方法(包括私有和保护)。但是PHP不存在这样的关键字。

问题是,受保护的方法只能从同一类或类的子类访问。您可以从父类扩展子类,如下所示:

class Child extends Parent
{
    public function __constructor ()
    {
        parent::__constructor();
    }

    public function __destroy()
    {
        $this->callme(); // Should work!
    }
}
或者干脆将方法更改为public


顺便问一下,这段代码是不是你会用到的真正的代码?接收父对象的构造函数似乎是错误的。你想做什么?

我对你的问题的评论解释了为什么它不起作用。这个答案显示了一种方法,可以根据您的澄清来完成您的要求,
MyChild
不应扩展
MyParent

这是一个黑客示例,它利用了一个事实,即只要您共享受保护方法的祖先,php就不关心您是否在自己以外的其他实例上调用受保护方法

我不得不对代码进行一些修改,使其成为有效的php
\u构造函数
不是php构造函数的名称

hacky.php

<?php

class Observer
{
    protected function callme()
    {
        echo 'I was called from ' . get_called_class(), PHP_EOL;
    }
}

class MyParent extends Observer
{
    public function createMyChild()
    {
        $this->callme(); // this is OK
        return new MyChild ($this);
    }
}

class MyChild extends Observer // hackey extends
{
    private $myMyParent;
    public function __construct($myMyParent)
    {
        $this->myMyParent = $myMyParent;
        $this->myMyParent->callme();
    }
}

$p = new MyParent;
$c = $p->createMyChild();

我想我找到了解决办法:

class Parent extends Observer
{
    function createChild()
    {
        $this->callme(); // this is OK
        return new Child (function() { $this->callme(); });
    }
}

class Child
{
    private $gatewayFunction;
    public function __constructor (Closure $gatewayFunction)
    {
        $this->gatewayFunction = $gatewayFunction;
    }

    public function __destroy()
    {
        $this->gatewayFunction->__invoke();
    }
}

谁会去拉屎?:)

如果您想公开访问它,为什么它会受到保护?只需像应该的那样公开它。除非扩展父级,否则它不是子级。在您的示例中,
child
Observer
parent
不在同一类层次结构中,因此它不能调用
Observer::callme()
。您的类名表明,您的意思是让
Parent
成为
Child
的超类,但这不是代码所说的。在
Parent
内部实例化一个新的
Child
对象不会使
Child
成为
观察者的子类,因此受保护的方法
callme()
在其内部不可用。。。是的,没关系,但这个建筑不是那样的。只有一个“家长”和许多“孩子”——任。“Child”不是一个真正的“Child”,而是一个包含的对象。为什么你不分享你真正的代码,或者至少更好地了解你想要做什么,这里有很多经验丰富的开发人员可以帮助你进行架构设计,包括我自己:Dyea我听说了Friends这不是玩笑,这是一个真正的解决方案。它既漂亮又脏
class Parent extends Observer
{
    function createChild()
    {
        $this->callme(); // this is OK
        return new Child (function() { $this->callme(); });
    }
}

class Child
{
    private $gatewayFunction;
    public function __constructor (Closure $gatewayFunction)
    {
        $this->gatewayFunction = $gatewayFunction;
    }

    public function __destroy()
    {
        $this->gatewayFunction->__invoke();
    }
}