"Ukazatel" na anonymní funkce ve třídě rubrika: Programování: PHP

4 Milan Suk
položil/-a 10.11.2014

Řeším následující problém: mám třídu, která obstarává běh formuláře a potřebuji kontrolovat validitu vstupů. Pokud to nějak lze udělat, potřeboval bych pomocí metody předat referenci na anonymní třídu do vlastnosti a pak tělo této funkce v hodný okamžik zavolat. Schematicky něco takového:

class form {
   $this->err_func;
 
   public function onError($func) {
      $this->err_func = $func;
   }
 
   public function anotherEvent($params) {
      $this->err_func($params);
   }
}

Jde vůbec něco takového v PHP udělat? Jak? Popř. existuje jiné/lepší řešení?

odkaz Vyřešeno
9 Taco
odpověděl/-a 10.11.2014

Lze:

class form {
   private $err_func;
 
   public function onError(Closure $func) {
      $this->err_func = $func;
   }
 
   public function anotherEvent($params) {
      $fn = $this->err_func;
      $fn($params);
   }
}

Tedy, problém je čistě syntaktické omezení.

Existuje i IMHO jiné/lepší řešení. Spočívající hlavně v tom, že to spoustu věcí už řeší za tebe.

Komentáře

  • maryo : Volat rovnou jako $fn($params) jde jen Closure nebo objekt s magickou metodou __invoke. Pak tam máš tu podmínku na is_callable zbytečně a vlastně i špatně, to už je lepší tam dát rovnou typehint Closure. Ale typehint Closure doporučuju používat jen v private metodách (třeba Doctrine to používá u kolekcí, což mě pěkně štve, protože libovolnej callback tam předat nejde viz https://github.com/doctrine/collections/blob/master/lib/Doctrine/Common/...) kde to voláš sám. Is_callable vrací true pro všechny callable, což může být Closure, pole o dvou prvcích (objekt + název metody případně název třídy + název statický metody), řetězec (název funkce případně název třídy a statický metody ve tvaru "Class::method") nebo objekt s tou magickou metodou __invoke. Volá se to pomocí funkce call_user_func nebo call_user_func_array($function, $arguments) když chceš předat ty parametry. Ta Nette fíčura mi nepřijde nejštastnější, lidi to používaj a vlastně ani neví jak to pořádně funguje. Zas takovej problém zavolat call_user_func není. 10.11.2014
  • Taco : @maryo: Ohledně toho closure máš pochopitelně pravdu. Upravil jsem to. (Ne, že by to teď bylo neprůstřelné, ale alespoň už to tolik neřve.) 10.11.2014

Pro zobrazení všech 2 odpovědí se prosím přihlaste:

Rychlé přihlášení přes sociální sítě:

Nebo se přihlaste jménem a heslem:

Zadejte prosím svou e-mailovou adresu.
Zadejte své heslo.