通过__call实现通知接口方法?

Hai*_*ood 8 php inheritance interface magic-methods laravel

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

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

我想知道的是,除了具有一堆其他public function find($id){return parent::find($id)}的车型类型的方法是不要延长雄辩模型有一种简单的方法,让界面知道该方法是通过处理__call

Gab*_*iel 7

虽然关于这种设计的清洁度可能存在更大的问题,但您可以通过使用实现接口方法的特征来完成类似于此的事情:

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 FindableTrait;
}

class NonmagicalUser implements FindableContract {
    public function find($id) {
        return "User $id was found to be nonmagical.  Let's burn him anyway.";
    }
}

print (new User)->find(123);
print (new NonmagicalUser)->find(321);
Run Code Online (Sandbox Code Playgroud)

  • 最后,我决定投票,因为我认为这确实很聪明。我犹豫了一下,因为我认为它真的很聪明。 (2认同)

hek*_*mgl 4

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

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