12

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

我在接口中声明了这些方法,因为不是所有实现接口的东西都会扩展 eloquent,所以我在接口中声明它们,这样我的应用程序总是知道这些方法会在那里。

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

4

2 回答 2

10

尽管对于这种设计的简洁性可能存在更大的问题,但您可以通过使用实现接口方法的 trait 来完成类似的事情:

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);
于 2015-02-08T21:55:30.987 回答
3

不,这是行不通的。虽然__call()对于动态编码风格非常好,但缺点是您无法在接口中强制执行动态方法的签名,并且您不会获得它的自动文档。

但是我认为,如果您想为这些方法创建接口,则应该不再需要使用__call()。我只是对方法进行硬编码。

于 2013-06-24T02:01:52.017 回答