如何访问特征中的类成员(或获得类似的行为)?

时间:2015-09-02 22:15:53

标签: php inheritance

这是我之前关于resolving the diamond issue in php的问题的后续跟踪。

正如我在该问题中所述,我通过使用 traits 并将实例传递给特征的方法来解决我的问题。如:

trait SecurityTrait
{
    public function beforeExecuteRouteTrait($controller, Dispatcher $dispatcher)
    {
        // Do something that makes use of methods/members of the controller
    }
}

class AppController extends Controller
{
    use SecurityTrait;

    public function beforeExecuteRoute(Dispatcher $dispatcher)
    {
        return $this->beforeExecuteRouteTrait($this, $dispatcher);
    }
}

然而,我仍然对此感到不安,因为我不认为这是 traits 应该如何使用。在我的阅读中,我没有找到任何方式来访问 traits中的类成员 (在 trait中创建$this 使用它)。这可能吗?或者是否有其他方法来实现类似的行为?

阅读了一些答案......

以前我认为在特质中使用$this->...时我收到了错误,这让我相信特质无法访问与底层类有关的任何内容。在阅读完答案之后,我尝试改变我的代码,再次在一个特征中使用$this->...并且它有效 - 这意味着几个星期前的拼写错误给了我太多头痛......

之前给出的示例现在看起来像这样

trait SecurityTrait
{
    public function beforeExecuteRoute(Dispatcher $dispatcher)
    {
        // Do something that makes use of methods/members of the controller
    }
}

class AppController extends Controller
{
    use SecurityTrait;
}

更清洁,更容易理解,但提供相同的功能。

2 个答案:

答案 0 :(得分:6)

如果你在一个类中使用一个特征,那么该特征可以完全访问所有类的成员,反之亦然 - 你可以从类本身调用私有特征方法。

将traits视为字面上被复制/粘贴到类体中的代码。

例如:

trait Helper
{
    public function getName()
    {
        return $this->name;
    }

    private function getClassName()
    {
        return get_class($this);
    }
}

class Example
{
    use Helper;

    private $name = 'example';

    public function callPrivateMethod()
    {
        // call a private method on a trait
        return $this->getClassName();
    }
}

$e = new Example();
print $e->getName(); // results in "example"
print $e->callPrivateMethod(); // results in "Example"

在我看来,引用特征中的类并不是使用它们的最佳方式,但没有什么可以阻止任何人这样做。

答案 1 :(得分:1)

不,这正是Traits的用途。您的班级已经extends一个班级,因此您无法继承任何其他班级的方法和变量。

想象一下Trait,比如复制/粘贴代码执行。当一个班级包含一个特质时,就好像你已经将所有代码写入了班级本身一样。