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

时间:2015-09-11 17:51:24

标签: php oop

这是类结构。我想Observer:callme()也可以从Children调用。

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!
    }
}

那么如何使FAIL工作? (不公开,因为它仅用于内部"父母"及其"儿童")

4 个答案:

答案 0 :(得分:2)

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

在C ++中有friend关键字来实现你想要的:你可以将Child定义为Observer的friend(这必须在Observer中完成),然后你可以调用所有方法在Child的方法中的Observer(包括private和protected)中。但PHP不存在这样的关键字。

答案 1 :(得分:2)

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

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

    public function __destroy()
    {
        $this->callme(); // Should work!
    }
}

或者只是将方法更改为公开。

而且,顺便说一下,这段代码是否会使用某种真正的代码?接收父对象的构造函数似乎是错误的。你想要完成什么?

答案 2 :(得分:1)

我对您的问题的评论解释了为什么它不起作用。这个答案显示了根据您MyChild不应扩展MyParent的说明来完成您所要求的内容的方法。

这是一个黑客的例子,只要你共享受保护方法的祖先,如果你在自己以外的其他实例上调用受保护的方法,那么它就可以利用php不关心的事实。

我不得不更改代码以使其成为有效的PHP。 __constructor不是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();

<强>结果:

$ php hacky.php
I was called from MyParent
I was called from MyParent

答案 3 :(得分:0)

我想我找到了解决方案:

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();
    }
}

谁会自欺欺人? :)