2013-06-24 23 views
6

Mam interfejs, który deklaruje metody potrzeb realizacji, takie jak find, findOrFail itp., W zasadzie elokwentnych metod Laravel.informowanie o metodach interfejsu są realizowane za pośrednictwem __call?

Deklaruję te metody w interfejsie, ponieważ nie wszystko, co implementuje interfejs, wydłuży wymowę, dlatego deklaruję je w interfejsie, więc moja aplikacja zawsze wie, jakie metody będą tam dostępne.

Co chcę wiedzieć, inne niż posiadające kilka public function find($id){return parent::find($id)} metod typu w modelach zrobienia przedłużyć wymowne modelu to istnieje prosty sposób aby interfejs wiedzieć, że metoda jest obsługiwana poprzez __call?

+0

Patrz także: https: //bugs.php.net/bug.php?id=41162. –

Odpowiedz

3

Nie, to nie zadziała. Podczas gdy __call() jest naprawdę przyjemny dla dynamicznego stylu kodowania, wadą jest to, że nie można wymuszać podpisów metod dynamicznych w interfejsie i nie otrzymasz zautomatyzowanej dokumentacji dla tego interfejsu.

Ale myślę, że jeśli jesteś w punkcie, w którym chcesz utworzyć interfejs dla tych metod, nie powinno być już więcej potrzeby używania __call(). Ja po prostu hardcode metody.

+0

Wygląda na to, że masz problem z projektowaniem. Chciałbym pomóc, ale pytanie jest trochę niejasne. Czy możesz pokazać podstawowy przykład? – hek2mgl

4

Chociaż nie może być większe wątpliwości co do czystości takiej konstrukcji, można osiągnąć coś podobnego do tego, używając cechę, która implementuje metody interfejsu:

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); 
+1

W końcu postanowiłem przegłosować, ponieważ uważam, że jest naprawdę sprytny. Zawahałem się przez chwilę, ponieważ uważam, że jest naprawdę sprytny. –

+1

Zgadzam się z Dennis, ogólnie rzecz biorąc to bardzo zły pomysł. Podstawowym zastosowaniem czegoś takiego jest akademickie/ciekawość/słodycz. Prawdopodobnie nie powinno być używane w prawdziwym kodzie. – Gabriel