Let your classes live their own life
posted: December 27th, 2004 · by: Sven
Comparing Google’s results on querying “php event listener” with “java event listener” we could state: so far there’s not too much about events and listeners, observers and notifications in the PHP world, while these basic patterns have gained safe ground in Java, C++, ... for many years.
Thus, it’s no wonder that we’ll find matured Lifecycle implementations in the Java world like in JavaServer Faces, Geronimo, WebWork and others more. Afaik, there are some efforts on event driven application design in the PHP world though, some examples well worth to study are: WACT, Prado, Poseidon.
In this article we’ll examine how to implement a simple Lifecycle in PHP.
First, we’ll set up a simple event generating class. EventGenerator will be able to register listeners and call a method on them when an event gets raised.
(For the sake of simplicity, we won’t rely here on a separate Event class that’s usually used to pack information about the event’s type, where the event got fired, and what exactly happened.)
class EventGenerator {
private $listeners = array();
public function attachListener($listener) {
echo "attaching: " . get_class($listener) . "<br>";
$this->listeners[] = $listener;
}
protected function raiseEvent($method, $args) {
foreach ($this->listeners as $listener) {
if (method_exists($listener, $method)) {
call_user_func_array(
array($listener, $method), $args);
} else {
$msg = "method does not exist: $method";
throw new Exception($msg);
}
}
}
}
Now, we’ll extend this class to the Lifecycle class that’s responsible to cycle through some predefined stages. To keep it simple, we’ll choose the stages ‘init’, ‘execute’, ‘exit’. In dot.net, for example, there are much more stages like ’...’.
class Lifecycle extends EventGenerator {
private $stages = array('init', 'execute', 'exit');
public function run () {
$method = 'onStageEnter';
foreach ($this->stages as $stage) {
echo "We're ready to enter stage: $stage<br>";
$this->raiseEvent($method, array($stage));
}
}
}
So, when the Lifecycle’s run() method gets called, the Lifecycle will raise StageEnter events, each with the current stage as a parameter.
Next, we need a class that we can register as a listener to the EventGenerator class. To be able to respond to the StageEnter events of the Lifecycle, we’ll implement a single method onStageEnter() that relays to (not yet implemented) methods onInit(), onExecute() and onExit().
class LifecycleListener {
public function onStageEnter($stage) {
echo "entered $stage in " . get_class($this) . "<br>";
$method = 'on' . ucFirst ($stage);
if (method_exists($this, $method)) {
$this->$method();
}
}
}
We can now extend the LifecycleListener to some custom class that we want to respond to the Lifecycle. Therefore, we’ll refer to the Component example from our last article (A php way to simple class aggregation).
class Component extends LifecycleListener {
protected function onInit() {
echo
"We've arrived on stage: <b>init</b>.<br>" .
"So, let's intialize the party.<br>";
}
protected function onExecute() {
echo
"We've arrived on stage: <b>execute</b>.<br>" .
"Now, let's perform our play.<br>";
}
protected function onExit() {
echo
"We've arrived on stage: <b>exit</b>.<br>" .
"Finally, let's clean up the theater.<br>";
}
}
That’s self-explaining, isn’t it? In onInit(), onExecute() and onExit() we would implement our real-life business stuff just as needed for a concrete Component.
Now, we can go for a test:
$lifecycle = new Lifecycle(); $lifecycle->attachListener(new Component()); $lifecycle->run();
This will result in the following output:
attaching: Component We're ready to enter the stage: init We've arrived on stage: init. So, let's intialize the party. We're ready to enter the stage: execute We've arrived on stage: execute. Now, let's perform our play. We're ready to enter the stage: exit We've arrived on stage: exit. Finally, let's clean up the theater.
chat said March 31st, 2011 at 08:31 PM ¶
I left everything the same except for the following change:
attaching: Component We’re ready to enter the stage: init We’ve arrived on stage: init. So, let’s intialize the party. We’re ready to enter the stage: execute We’ve arrived on stage: execute. Now, let’s perform our play. We’re ready to enter the stage: exit We’ve arrived on stage: exit. Finally, let’s clean up the theater.
okey oyunu said May 12th, 2011 at 04:33 PM ¶
This is nice post. Thanks. Tüm dünya artik okey oyunu oynuyor. Yillardir bir çok oyun programi olmasina ragmen, içlerinden en güzeli olarak nitelendirebilecegimiz tek bir site göze çarpmaktadir. Diger tüm okey oyunu programlarinin aksine ücretsiz olmasi ve 3 boyutlu olarak hizmet vermesi mükemmel bir gelismedir. Sizlerde www.okey-oyunu.com adresinden bu essiz okey oyununu indirebilirsiniz. Kullanimi çok basit ve Türkçe dil seçenegi ile kolaylikla oyuna baslayabilirsiniz. Ister kendi ülkenizden, isterseniz dünyanin tüm farkli bölgelerinden dilediginiz oyun odalarini seçerek, oyuna hemen baslayabilirsiniz. Okey oyunu oynamak için artik arkadas bile aramaniza gerek kalmadan, bilgisayarinizdan 100 binlerce üye ile online olarak okey oyununu oynamanin zevkine varabilirsiniz.