通知接口方法通过__call实现


informing interface methods are implemented via __call?

我有一个接口,它声明实现需要find、findOrFail等方法,基本上是Laravel雄辩的方法。

我在接口中声明这些方法,因为并不是所有实现接口的东西都能雄辩地扩展,所以我在接口上声明它们,这样我的应用程序就永远知道这些方法会在那里。

我想知道的是,除了在扩展雄辩模型的模型中有一堆public function find($id){return parent::find($id)}类型的方法之外,还有一种简单的方法可以让接口知道该方法是通过__call处理的吗?

尽管这种设计的清洁度可能还有更大的问题,但您可以通过使用实现接口方法的特性来完成类似的事情:

interface FindableContract {
    public function find($id);
}
trait MagicFindableTrait {
    public function find($id) {
        return static::__call(__FUNCTION__, func_get_args()); 
    }
}
class MagicalParent {
    public function __call($method, $args) {
        if ($method == 'find') {
            return "User " . $args[0] . " is a witch! May we burn her?!";
        }
    }
}
class User extends MagicalParent implements FindableContract {
    use MagicFindableTrait;
}
class NonmagicalUser implements FindableContract {
    public function find($id) {
        return "User $id was found to be non-magical.  Let's burn him anyway.";
    }
}
print (new User)->find(123);
print (new NonmagicalUser)->find(321);

不,这将不起作用。虽然__call()对于动态编码风格来说真的很好,但它的缺点是你不能在接口中强制执行动态方法的签名,而且你不会得到它的自动文档

但我认为,如果您想为这些方法创建一个接口,就不需要再使用__call()了。我只想硬编码这些方法。