У меня есть интерфейс, который декларирует методы реализации, такие как find, findOrFail и т. Д., В основном, красноречивые методы Laravel.
Я объявляю эти методы в интерфейсе, потому что не все, что реализует интерфейс, будет красноречивым, поэтому я объявляю их в интерфейсе, поэтому мое приложение всегда знает, что методы будут там.
Я хочу знать, кроме того, что у вас есть куча методов public function find($id){return parent::find($id)}
общих 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 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);
Нет, это не сработает. В то время как __call()
действительно хорош для стиля динамического кодирования, недостатками являются то, что вы не можете принудительно применять сигнатуры динамических методов в интерфейсе, и вы не получите автоматическую документацию для него.
Но я думаю, что если вы находитесь в точке, где хотите создать интерфейс для этих методов, больше не нужно будет использовать __call()
. Я бы просто жестко программировал методы.