Autor Zpráva
alex65
Profil *
Zdravím.

Snažím se si napsat systém pro události v mém projektu. Mám jasnou logiku.

Event::register("page.created", "Log::Write", "Page created");
// ...
Event::fire("page.created");


Jenže nevím jak mám uchovávat ty zaregistrované funkce. Jde o to že mám kód rozdělený do více Controllerů apod. A na stránce třeba web.cz/page/show/xxxx-yyyy se načte Controller pro Page a ta udělá
Event::fire("page.show.single");


ale neví že na stránce třeba Controller pro stránku User si zaregistroval právě do takové události svou funkci. Ten Controller pro Page to neví, protože User se načte jen na /user/.

Takže jde o to jak uchovávat tyto události, do DB? Do souborů? Nebo existuje elegantnější způsob?
Doufám že jsem popsal svůj problém srozumitelně.

Děkuji za rady.
Tori
Profil
alex65:
ale [Page Controller] neví že na stránce třeba Controller pro stránku User si zaregistroval právě do takové události svou funkci.
Nedávno jsem si napsala podobnou třídu a handlery pro jednotlivé události z podobného důvodu registruji už v bootstrapu, ještě před zavoláním kontroleru.

jak uchovávat tyto události
Třeba pole uvnitř třídy Event, kde klíčem je název události.
Pokud jsou ty události v nějaké hierarchii (že např. callback registrovaný pro "page.show" se zavolá i při "page.show.cokoli"), tak asi vícerozměrné pole, kde se při vyvolání události "page.single.show" zavolají všechny callbacky z $callback[page], $callback[page][single] a $callback[page][single][show]. Aspoň teda něco takového bych použila.

Btw Event::fire by mohla mít volitelný 2.parametr pro doplňující info (třeba název vytvářené stránky apod.)
Mastodont
Profil
Způsob registrace v poli máš popsaný třeba na
http://query7.com/writing-an-event-system-in-php
Otázkou ovšem je, zda je vhodné do PHP roubovat události, když zpracování kódu má lineární a konečný průběh a chybí tu trvale existující objekty typu servlety v JSP. Ale to si musíš vyřešit sám.
Tori
Profil
Mastodont:
Otázkou ovšem je, zda je vhodné do PHP roubovat události, když zpracování kódu má lineární a konečný průběh
To sice ano, ale zase to podporuje vzájemnou nezávislost objektů. Kontrolery (i jiné objekty) můžou posílat všechny zprávy na jedno místo a nestarat se o to, které z nich půjdou do logu a které na obrazovku a které se zobrazí v závislosti na serveru.
alex65
Profil *
Není problém to napsat a události uchovávat v poli. Jen jde o to aby to bylo perzistentní.
Dejme tomu že máme -
class User extends Plugin implements IPlugin
{

  public function __construct()
  {
   Event::register("page.created", "User::DoSomeStuff", "Page created");
  }
  
  public static function DoSomeStuff()
  {
    //nějaká akce
  }

}


Jenže tato třída se načte pouze v url web.cz/user/xxxx. Tudíž když někdo bude třeba na web.cz/page/create/ kde se v dané metodě spustí sada registrovaných eventů tak nebude mít ponětí o tom že si to User registroval.

Tzn. pokud uvažuji správně tak bych musel provést minimálně __construct každé třídy (= Pluginu). Což by asi nebylo efektivní.
Další možností je to ukládat do DB třeba :
Event::register("page.created", "Log::Write", "Page created", $persist = true);


Nebo další možností je udělat speciální typ třeba

class EventUser extends Event
{
 public function onPageCreated()
 {
   //do some stuff
 } 
}


Jiné možnosti pro perzistentní uložení události mě nenapadají.
Tori
Profil
alex65
Myslela jsem to tak, že Event::register by nemuselo být uvnitř konstruktoru třídy User, ale úplně mimo třídu.
// bootstrap (index.php)
//.. nastavení prostředí, autoloaderu, atd.
Event::register("page.created", "User::DoSomeStuff", "Page created");
Event::register("page.created", "Log::write", "Page created");
Event::register("page.deleted", "Log::write", "Page deleted");
// ... router, předání řízení kontroleru.


↓ Aha, neuvědomila jsem si, že jde o pluginy.
alex65
Profil *
To jsem pochopil, ale už to podle mě tím pádem ztrácí určitou "automatizaci".
Takhle to musím ručně psát, přičemž by bylo lepší to automatizovat a pro tohle mě nic jiného než právě to určité perzistentní uložení těch eventů nevidím.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: