Lanes Skrevet 25. november 2014 Del Skrevet 25. november 2014 (endret) Jeg trenger litt bistand til å finne en ryddig måte å løse dette på, da jeg ikke er fornøyd med mine egne forsøk. Jeg har et ferdigbygd system for event dispatching, men jeg ønsker å utbedre dette til å akseptere wildcards. Systemet er inspirert av Symfony sin løsning, og likner derfor en del. Det innebærer at en event trigges med følgende linje (eller noe slikt, skriver fra minne nå): $eventDispatcher->dispatch('controllers.mycontroller.eventname', $event); og en listeners defineres slik: $eventDispatcher->addListener(array($listener, 'methodToTrigger'), 'controllers.mycontroller.eventname'); Dette fører til at alle listeners som lytter etter eventen med navn 'controllers.mycontroller.eventname' trigger. So far so good. Det jeg derimot nå ønsker er som sagt å støtte wildcards, så jeg vil at en listener skal kunne lytte etter, f.eks: *.mycontroller.eventname controllers.* eventname Alle eksemplene over burde trigge på 'controllers.mycontroller.eventname'. Jeg har lekt meg litt på papiret med hvordan dette kan gjøres, men jeg føler ikke at jeg finner noen ryddig løsning, og at dette burde være noe det finnes en eller annen standard metode for. Edit: Merk at jeg kun ønsker å endre en enkel metode i dispatcher systmet mitt, jeg trenger kun en eller annen funksjon som returnerer true/false dersom det er et treff. Endret 25. november 2014 av Lanes Lenke til kommentar
Lanes Skrevet 27. november 2014 Forfatter Del Skrevet 27. november 2014 (endret) Litt overraskende at det ikke har kommet noen svar her. Det pleier å være såpass appetitt etter litt aktivitet på dette forumet at de kommer raskt.Jeg fikk nå likevel satt meg ned og tenkt ut en litt annen løsning enn hva jeg først så for meg, så det er mulig at dette vil fungere. Merk at jeg ikke har testet koden enda da jeg skrev det på iPaden under under frokost i dag tidlig.Dette føles derimot fremdeles litt mer tungvint enn hva det burde være. public function dispatch($sEventIdentifier, Event $event) { $aEventPathElements = explode(".", $sEventIdentifier); $sEventName = array_pop($aEventPathElements); $iEventPathElements = count($aEventPathElements); foreach ($this->aListeners as $sListenerFullPath => $callback) { $aListenerPathElements = explode(".", $sListenerFullPath); $sListenerEventName = array_pop($aListenerPathElements); $iListenerPathElements = count($aListenerPathElements); // Dersom det kun er satt eventname i listener sjekker vi mot denne if ($iListenerPathElements === 0) { if ($sListenerEventTarget == $sEventName) { call_user_func($callback, $event, $this); continue; } } // Beveg oss nedover og sjekk hvert element $bMatch = false; for ($i; $i == $iEventPathElements;$i++) { if ($aEventPathElements[$i] == $aListenerPathElements[$i] || $aListenerPathElements[$i] == "*") { $bMatch = true; } ($bMatch) ? continue : break; } // Kommer vi hit er $bMatch true i alle elementene, og vi har // en match i alle ledd og kan kalle listener objektet call_user_func($callback, $event, $this); } } Koden over må fordeles i egne methods, men flyten er den samme. Endret 27. november 2014 av Lanes Lenke til kommentar
Lanes Skrevet 10. desember 2014 Forfatter Del Skrevet 10. desember 2014 (endret) Det ble virkelig en monolog dette her Koden over var bare rot, så jeg tenkte å i det minste poste hva jeg endte opp med. Føler fremdeles at dette kan gjøres mye enklere med noen smarte regex løsninger... Gidder ikke å skrive om koden til en mer lettforståelig del, så dette blir min implementasjon direkte i min applikasjon. Hovedsaken er at den tar to stringer i formatet namespace.subnamespace.class og sjekker de opp mot hverandre for å se om de er like, og da selvfølgelig med støtte for wildcards. private function extractDataFromEventIdentifier($sEventIdentifier) { $aEventPathElements = explode(".", $sEventIdentifier); $sEventName = end($aEventPathElements); $sFirstElement = reset($aEventPathElements); return array( 'sEventName' => $sEventName, 'aEventPathElements' => $aEventPathElements, 'iEventPathElements' => count($aEventPathElements), 'sFirstElement' => $sFirstElement ); } private function isMatch($aEventData, $aListenerData) { if($aListenerData['iEventPathElements'] === 1 && $aListenerData['sEventName'] == $aEventData['sEventName']) { return true; } if ($aListenerData['sFirstElement'] == '*') { $aEventData['aEventPathElements'] = array_reverse($aEventData['aEventPathElements']); $aListenerData['aEventPathElements'] = array_reverse($aListenerData['aEventPathElements']); } return $this->checkForMatch($aEventData, $aListenerData); } private function checkForMatch(array $aEventData, array $aListenerData) { foreach($aEventData['aEventPathElements'] as $key => $sElementToMatch) { $sElement = array_slice($aListenerData['aEventPathElements'], $key, 1); if(isset($sElement[0])) { $sElement = $sElement[0]; } else { continue; } if($sElement == '*') { $bMatch = true; continue; } else if ($sElementToMatch == $sElement) { $bMatch = true; continue; } else { return false; } } return $bMatch; } Endret 10. desember 2014 av Lanes Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå