PHP中是否有类似特性的接口?

cfk*_*ane 5 php

我经常发现自己希望能够让 trait 实现一个接口,这样当我将 trait 添加到类中时,我可以知道满足了 trait 的要求。例如,在 Laravel 中,我将为我的许多关系创建特征,如下所示:

trait HasOwner
{
    public function owner()
    {
        return $this->belongsTo(User::class);
    }
}
Run Code Online (Sandbox Code Playgroud)

在 Laravel 的情况下,我可以非常确定我添加它的每个模型都将有一个 ownsTo 方法,但是我仍然觉得我应该能够强制执行这个。

我知道强制执行此操作的唯一方法是使用 HasOwnerInterface 或 HasRelationshipsInterface 来支持它,但事实上,当我添加特性时未能添加它会防止它发出吱吱声,感觉就像在车上安装了安全气囊,但您需要这样做每次启动发动机时打开。

这是我认为将是完美的:

trait HasOwner expects RelationshipInterface
{
    public function owner()
    {
        return $this->belongsTo(User::class);
    }
}

interface RelationshipInterface
{
    public function belongsTo(Model $model): Relationship;
}

class Property implements RelationshipInterface
{
    use HasOwner;
}
Run Code Online (Sandbox Code Playgroud)

我应该为此使用另一种设计模式,还是我应该鼓起勇气,开始与 PHP 核心团队为此而战以添加它?

rai*_*7ow 4

请记住,特征本质上只是“自动复制粘贴”的语法糖,因此您不能直接将典型的 OOP 技术应用于它们。按照目前的情况(2021 年 6 月),通过对具有抽象方法的使用特征的类施加至少一些要求,您可能会更接近:

\n
\n

特征支持使用抽象方法,以便对展示类施加\n要求。支持公共、受保护和私有\n方法。在 PHP 8.0.0 之前,仅支持公共和受保护的\n抽象方法。

\n
\n
<?php\ntrait Hello {\n    public function sayHelloWorld() {\n        echo \'Hello\'.$this->getWorld();\n    }\n    abstract public function getWorld();\n}\n\nclass MyHelloWorld {\n    private $world;\n    use Hello;\n    public function getWorld() {\n        return $this->world;\n    }\n    public function setWorld($val) {\n        $this->world = $val;\n    }\n}\n?>\n
Run Code Online (Sandbox Code Playgroud)\n
\n

作为旁注,有一个现有的用于实现接口的特征的 RFC,于 2016 年提交(!)。这是关键引用:

\n
\n

第一个建议是允许一个特征声明它\n实现一个接口。让特征声明它实现\n接口使得接口\n(规范)和特征(实现)之间的关系变得明确。

\n

该特征必须实现所有接口实现的每个方法。如果不这样做将是一个致命的错误。方法声明必须与接口兼容。部分或全部 Trait\xe2\x80\x99 实现方法可能是抽象的,其中包含提供方法实现的 Trait 的类(类似于实现接口的抽象类)。

\n
\n

不过,到目前为止,该 RFC 的进展甚微。不清楚原因;虽然提案 2 存在一个悬而未决的问题(关于将接口从特征传播到类),但提案 1 似乎没有任何问题。预计该方案也不会发生重大更改。

\n