PHP hook, building hooks in your application
Introduction
One of the real challenges in building any type of framework, core or application is making it possible for the developers to hook into the business logic at specific points. Since PHP is not event based, nor it works with interrupts you have to come up an alternative.
The test case
Lets assume we are the main developers of a webshop framework. Programmers can use our framework to build complete webshops. Programmers can manage the orders that are placed on the webshop with the order class. The order class is part of our framework and we don’t want it to be extended by any programmer. However we don’t want to limit to programmers in their possibilities to hook into the orders process.
For example programmers should be able to send an email to the webshopowner if an order changes from one specific delivery status to another. This functionality is not part of the default behavior in our framework and is custom for the progammers webshop implementation.
Like said before, PHP doesn’t provide interrupts or real events so we need to come up with another way to implement hooks into our application. Lets take a look at the observer pattern.
Implementing the Observer pattern
The observer pattern is a design-pattern that describes a way for objects to be notified to specific state-changes in objects of the application.
For the first implementation we can use SPL. The SPL provides in two simple objects:
SPLSubject
- attach (new observer to attach)
- detach (existing observer to detach)
- notify (notify all observers)
SPLObserver
- update (Called from the subject (i.e. when it’s value has changed).
iOrderRef = $iOrderRef;
// Get order information from the database or an other resources
$this->iStatus = Order::STATUS_SHIPPED;
}
/**
* Attach an observer
*
* @param SplObserver $oObserver
* @return void
*/
public function attach(SplObserver $oObserver)
{
$sHash = spl_object_hash($oObserver);
if (isset($this->aObservers[$sHash])) {
throw new Exception('Observer is already attached');
}
$this->aObservers[$sHash] = $oObserver;
}
/**
* Detach observer
*
* @param SplObserver $oObserver
* @return void
*/
public function detach(SplObserver $oObserver)
{
$sHash = spl_object_hash($oObserver);
if (!isset($this->aObservers[$sHash])) {
throw new Exception('Observer not attached');
}
unset($this->aObservers[$sHash]);
}
/**
* Notify the attached observers
*
* @param string $sEvent, name of the event
* @param mixed $mData, optional data that is not directly available for the observers
* @return void
*/
public function notify()
{
foreach ($this->aObservers as $oObserver) {
try {
$oObserver->update($this);
} catch(Exception $e) {
}
}
}
/**
* Add an order
*
* @param array $aOrder
* @return void
*/
public function delete()
{
$this->notify();
}
/**
* Return the order reference number
*
* @return int
*/
public function getRef()
{
return $this->iOrderRef;
}
/**
* Return the current order status
*
* @return int
*/
public function getStatus()
{
return $this->iStatus;
}
/**
* Update the order status
*/
public function updateStatus($iStatus)
{
$this->notify();
// ...
$this->iStatus = $iStatus;
// ...
$this->notify();
}
}
/**
* Order status handler, observer that sends an email to secretary
* if the status of an order changes from shipped to delivered, so the
* secratary can make a phone call to our customer to ask for his opinion about the service
*
* @package Shop
*/
class OrderStatusHandler implements SplObserver
{
/**
* Previous orderstatus
* @var int
*/
protected $iPreviousOrderStatus;
/**
* Current orderstatus
* @var int
*/
protected $iCurrentOrderStatus;
/**
* Update, called by the observable object order
*
* @param Observable_Interface $oSubject
* @param string $sEvent
* @param mixed $mData
* @return void
*/
public function update(SplSubject $oSubject)
{
if(!$oSubject instanceof Order) {
return;
}
if(is_null($this->iPreviousOrderStatus)) {
$this->iPreviousOrderStatus = $oSubject->getStatus();
} else {
$this->iCurrentOrderStatus = $oSubject->getStatus();
if($this->iPreviousOrderStatus === Order::STATUS_SHIPPED && $this->iCurrentOrderStatus === Order::STATUS_DELIVERED) {
$sSubject = sprintf('Order number %d is shipped', $oSubject->getRef());
//mail('secratary@example.com', 'Order number %d is shipped', 'Text');
echo 'Mail sended to the secratary to help her remember to call our customer for a survey.';
}
}
}
}
$oOrder = new Order(26012011);
$oOrder->attach(new OrderStatusHandler());
$oOrder->updateStatus(Order::STATUS_DELIVERED);
$oOrder->delete();
?>
There are several problems with the implementation above. To most important disadvantage is that we have only one update method in our observer. In this update method we don’t know when and why we are getting notified, just that something happened. We should keep track of everything that happens in the subject. (Or use debug_backtrace… just joking, don’t even think about using it that way ever!).
Taking it a step further, events
Lets take a look at the next example, we will extend the Observer implementation with some an additional parameter for the eventname that occured.
Finishing up, optional data
iOrderRef = $iOrderRef;
// Get order information from the database or something else...
$this->iStatus = Order::STATUS_SHIPPED;
}
/**
* Attach an observer
*
* @param Observer_Interface $oObserver
* @return void
*/
public function attachObserver(Observer_Interface $oObserver)
{
$sHash = spl_object_hash($oObserver);
if (isset($this->aObservers[$sHash])) {
throw new Exception('Observer is already attached');
}
$this->aObservers[$sHash] = $oObserver;
}
/**
* Detach observer
*
* @param Observer_Interface $oObserver
* @return void
*/
public function detachObserver(Observer_Interface $oObserver)
{
$sHash = spl_object_hash($oObserver);
if (!isset($this->aObservers[$sHash])) {
throw new Exception('Observer not attached');
}
unset($this->aObservers[$sHash]);
}
/**
* Notify the attached observers
*
* @param string $sEvent, name of the event
* @param mixed $mData, optional data that is not directly available for the observers
* @return void
*/
public function notifyObserver($sEvent, $mData=null)
{
foreach ($this->aObservers as $oObserver) {
try {
$oObserver->update($this, $sEvent, $mData);
} catch(Exception $e) {
}
}
}
/**
* Add an order
*
* @param array $aOrder
* @return void
*/
public function add($aOrder = array())
{
$this->notifyObserver('onAdd');
}
/**
* Return the order reference number
*
* @return int
*/
public function getRef()
{
return $this->iOrderRef;
}
/**
* Return the current order status
*
* @return int
*/
public function getStatus()
{
return $this->iStatus;
}
/**
* Update the order status
*/
public function updateStatus($iStatus)
{
$this->notifyObserver('onBeforeUpdateStatus');
// ...
$this->iStatus = $iStatus;
// ...
$this->notifyObserver('onAfterUpdateStatus');
}
}
/**
* Order status handler, observer that sends an email to secretary
* if the status of an order changes from shipped to delivered, so the
* secratary can make a phone call to our customer to ask for his opinion about the service
*
* @package Shop
*/
class OrderStatusHandler implements Observer_Interface
{
protected $iPreviousOrderStatus;
protected $iCurrentOrderStatus;
/**
* Update, called by the observable object order
*
* @param Observable_Interface $oObservable
* @param string $sEvent
* @param mixed $mData
* @return void
*/
public function update(Observable_Interface $oObservable, $sEvent, $mData=null)
{
if(!$oObservable instanceof Order) {
return;
}
switch($sEvent) {
case 'onBeforeUpdateStatus':
$this->iPreviousOrderStatus = $oObservable->getStatus();
return;
case 'onAfterUpdateStatus':
$this->iCurrentOrderStatus = $oObservable->getStatus();
if($this->iPreviousOrderStatus === Order::STATUS_SHIPPED && $this->iCurrentOrderStatus === Order::STATUS_DELIVERED) {
$sSubject = sprintf('Order number %d is shipped', $oObservable->getRef());
//mail('secratary@example.com', 'Order number %d is shipped', 'Text');
echo 'Mail sended to the secratary to help her remember to call our customer for a survey.';
}
}
}
}
$oOrder = new Order(26012011);
$oOrder->attachObserver(new OrderStatusHandler());
$oOrder->updateStatus(Order::STATUS_DELIVERED);
$oOrder->add();
?>
Now we are able to take action on different events that occur.
Disadvantages
Although this implementation works quite well there are some drawbacks. One of those drawbacks is that we need to dispatch an event in our framework, if we don’t programmers can’t hook into our application. Triggering events everywhere give us a small performance penalty however I do think this way of working gives the programmers a nice way to hook into your application on those spots that you want them to hook in.
Just for the record
Notice that this code is just an example and can still use some improvements, for example: each observer is initialized even it will maybe never be notified, therefore I suggest to make use of lazy in some cases for loading the objects. There are other systems to hook into an application, more to follow!
Hi there, I desire to subscribe for this blog to obtain hottest updates,
so where can i do it please assist.
pet wellness exam
28 Oct 25 at 6:56 am
I think that is among the so much vital information for me.
And i’m happy studying your article. But want to commentary on few
basic things, The web site style is perfect, the articles is really excellent : D.
Excellent process, cheers
ankara kürtaj
28 Oct 25 at 6:56 am
kraken онлайн
кракен клиент
Henryamerb
28 Oct 25 at 6:58 am
купить диплом в чебоксарах [url=https://rudik-diplom10.ru/]купить диплом в чебоксарах[/url] .
Diplomi_mgSa
28 Oct 25 at 6:58 am
Thanks very nice blog!
Gulf Shores luxury custom home builders
28 Oct 25 at 6:58 am
Hi! Someone in my Facebook group shared this website with us so I came to check it out.
I’m definitely loving the information. I’m book-marking and
will be tweeting this to my followers! Wonderful blog and brilliant design and style.
band flumberico
28 Oct 25 at 6:59 am
подвал дома ремонт [url=https://gidroizolyaciya-podvala-cena.ru]https://gidroizolyaciya-podvala-cena.ru[/url] .
gidroizolyaciya podvala cena_brKt
28 Oct 25 at 6:59 am
анонимная наркологическая помощь в москве [url=https://narkologicheskaya-klinika-28.ru/]анонимная наркологическая помощь в москве[/url] .
narkologicheskaya klinika_voMa
28 Oct 25 at 7:00 am
Erfahrungen mit Kamagra 100mg: vitalpharma24 – Potenzmittel ohne ärztliches Rezept
RichardImmon
28 Oct 25 at 7:00 am
наплавляемая гидроизоляция цена [url=http://gidroizolyaciya-cena-8.ru/]наплавляемая гидроизоляция цена[/url] .
gidroizolyaciya cena_tdKn
28 Oct 25 at 7:00 am
купить диплом техникума кемерово [url=http://www.frei-diplom9.ru]купить диплом техникума кемерово[/url] .
Diplomi_twea
28 Oct 25 at 7:01 am
можно ли купить легальный диплом [url=http://frei-diplom5.ru/]http://frei-diplom5.ru/[/url] .
Diplomi_vuPa
28 Oct 25 at 7:01 am
диплом проведенный купить [url=www.frei-diplom2.ru/]диплом проведенный купить[/url] .
Diplomi_ksEa
28 Oct 25 at 7:02 am
наркологическая клиника трезвый выбор [url=https://narkologicheskaya-klinika-25.ru/]narkologicheskaya-klinika-25.ru[/url] .
narkologicheskaya klinika_xgPl
28 Oct 25 at 7:02 am
купить диплом в междуреченске [url=www.rudik-diplom11.ru/]www.rudik-diplom11.ru/[/url] .
Diplomi_nqMi
28 Oct 25 at 7:03 am
ремонт подвала в частном доме [url=gidroizolyaciya-podvala-cena.ru]gidroizolyaciya-podvala-cena.ru[/url] .
gidroizolyaciya podvala cena_zmKt
28 Oct 25 at 7:03 am
наркологические клиники москвы [url=https://narkologicheskaya-klinika-25.ru/]наркологические клиники москвы[/url] .
narkologicheskaya klinika_xtPl
28 Oct 25 at 7:05 am
купить диплом колледжа всего [url=frei-diplom9.ru]frei-diplom9.ru[/url] .
Diplomi_gqea
28 Oct 25 at 7:06 am
купить диплом в орле [url=http://rudik-diplom8.ru/]http://rudik-diplom8.ru/[/url] .
Diplomi_cbMt
28 Oct 25 at 7:06 am
кракен маркет
кракен актуальная ссылка
Henryamerb
28 Oct 25 at 7:06 am
купить проведенный диплом провести [url=http://frei-diplom2.ru/]купить проведенный диплом провести[/url] .
Diplomi_czEa
28 Oct 25 at 7:06 am
наркологическая служба [url=https://www.narkologicheskaya-klinika-28.ru]наркологическая служба[/url] .
narkologicheskaya klinika_coMa
28 Oct 25 at 7:07 am
кракен обмен
kraken обмен
Henryamerb
28 Oct 25 at 7:07 am
купить диплом диспетчера [url=www.rudik-diplom5.ru]купить диплом диспетчера[/url] .
Diplomi_hsma
28 Oct 25 at 7:07 am
Aiyo, minus strong mathematics іn Junior College, еvеn prestigious institution kids mаy falter at next-level algebra, thսѕ cultivate thiѕ promρtly leh.
Victoria Junior College cultivates imagination аnd
leadership, sparking enthusiasms fоr futurre creation. Coastal school centers support arts, humanities, ɑnd sciences.
Integrated programs ᴡith alliances սse seamless, enriched education. Service аnd global efforts construct caring, durable individuals.
Graduates lead ԝith conviction, attaining remarkable success.
Tampines Meridian Junior College, born fгom the lively
merger ⲟf Tampines Junnior College аnd Meridian Junior
College, ⲣrovides аn ingenious and culturally rich education highlighted Ƅy specialized electives іn drama
and Malay language, nurturing expressive аnd
multilingual skills іn а forward-thinking neighborhood.
Тhe college’s advanced facilities, incorporating theater ɑreas, commerce simulation
laboratories, ɑnd science innovation centers, support diverse academic streams tһɑt encourage interdisciplinary exploration аnd practical skill-building tһroughout
arts, sciences, аnd service. Talent development programs,
coupled ԝith abroad immersion trips and cultural festivals,
foster strong management qualities, cultural awareness, аnd versatility to global dynamics.
Within a caring аnd understanding campus culture, students tɑke рart in wellness
initiatives, peer support ѕystem, and co-curricular clᥙbs that
promote strength, emotional intelligence, ɑnd
collaborative spirit. Aѕ ɑ result, Tampines
Meridian Junior College’ѕ trainees achieve holistic growth ɑnd
ɑгe well-prepared tο tackle global difficulties,
Ьecoming positive, versatile people ɑll set fоr university success
аnd beyond.
Parents, kiasu mode engaged lah, solid primary mathematics гesults to superior science grasp аnd tech dreams.
Aiyah,primary math teaches real-ԝorld applications ѕuch as
money management, tһus guarantee your kid masters this correctly starting ʏoung.
Listen up, Singapore folks, math іѕ lіkely thе extremely essential primary discipline, encouraging innovation іn prߋblem-solving in groundbreakinbg
careers.
Ⅾo not play play lah, link a good Junior College plus math superiority tߋ guarantee superior А Levels marks and effortless shifts.
А-level distinctions in Math signal potential to recruiters.
Listen ᥙp, steady pom рі pi, maths remaіns paгt ᧐f the top topics
іn Junior College, laying foundation іn А-Level hiցheг calculations.
Βesides frօm establishment amenities, emphasize
ѡith math for stop frequent errors ѕuch as careless
errors ɗuring assessments.
Ꭺlso visit my webpage :: Zhenghua Secondary School
Zhenghua Secondary School
28 Oct 25 at 7:08 am
гидроизоляция подвала москва [url=https://gidroizolyaciya-cena-8.ru/]гидроизоляция подвала москва[/url] .
gidroizolyaciya cena_ipKn
28 Oct 25 at 7:10 am
kraken сайт
кракен вход
Henryamerb
28 Oct 25 at 7:12 am
вода в подвале [url=http://www.gidroizolyaciya-podvala-cena.ru]http://www.gidroizolyaciya-podvala-cena.ru[/url] .
gidroizolyaciya podvala cena_gdKt
28 Oct 25 at 7:13 am
наркологическая клиника анонимно [url=narkologicheskaya-klinika-28.ru]наркологическая клиника анонимно[/url] .
narkologicheskaya klinika_gpMa
28 Oct 25 at 7:13 am
гидроизоляция цена работы [url=http://gidroizolyaciya-cena-8.ru]гидроизоляция цена работы[/url] .
gidroizolyaciya cena_ziKn
28 Oct 25 at 7:14 am
купить новый диплом [url=http://rudik-diplom9.ru/]купить новый диплом[/url] .
Diplomi_fbei
28 Oct 25 at 7:15 am
купить напас
купить напас
28 Oct 25 at 7:15 am
Hello, I wish for to subscribe for this web site to obtain hottest updates, thus where
can i do it please help out.
dewa scatter
28 Oct 25 at 7:16 am
Howdy! Someone in my Myspace group shared this site with us so I came to check it
out. I’m definitely loving the information.
I’m bookmarking and will be tweeting this to my followers!
Fantastic blog and wonderful style and design.
turkey visa on arrival for australian
28 Oct 25 at 7:16 am
вертикальная гидроизоляция подвала [url=www.gidroizolyaciya-podvala-cena.ru]вертикальная гидроизоляция подвала[/url] .
gidroizolyaciya podvala cena_xiKt
28 Oct 25 at 7:17 am
контора мелбет [url=https://melbetofficialsite.ru/]контора мелбет[/url] .
bk melbet_dmEa
28 Oct 25 at 7:18 am
клиника вывод из запоя [url=http://narkologicheskaya-klinika-25.ru]http://narkologicheskaya-klinika-25.ru[/url] .
narkologicheskaya klinika_myPl
28 Oct 25 at 7:18 am
кракен vpn
kraken обмен
Henryamerb
28 Oct 25 at 7:18 am
наркология в москве [url=narkologicheskaya-klinika-27.ru]наркология в москве[/url] .
narkologicheskaya klinika_mipl
28 Oct 25 at 7:19 am
обмазочная гидроизоляция цена [url=http://gidroizolyaciya-cena-7.ru/]обмазочная гидроизоляция цена[/url] .
gidroizolyaciya cena_ufSi
28 Oct 25 at 7:22 am
Перед перечнем поясним логику: домашний визит уместен, когда обстановка безопасна, риски контролируемы и есть взрослый помощник на вечер и ночь. Ниже — ориентиры, при которых имеет смысл начать с выезда, а не со стационара.
Подробнее можно узнать тут – [url=https://narkolog-na-dom-voskresensk8.ru/]psihiatr-narkolog[/url]
Traviscot
28 Oct 25 at 7:22 am
где можно купить диплом техникума в челябинске [url=http://frei-diplom8.ru]где можно купить диплом техникума в челябинске[/url] .
Diplomi_hasr
28 Oct 25 at 7:22 am
наркологические услуги [url=www.narkologicheskaya-klinika-28.ru]наркологические услуги[/url] .
narkologicheskaya klinika_suMa
28 Oct 25 at 7:23 am
купить диплом техникума с занесением в реестр [url=http://www.frei-diplom9.ru]купить диплом техникума с занесением в реестр[/url] .
Diplomi_ebea
28 Oct 25 at 7:24 am
оптимизация сайта блог [url=statyi-o-marketinge6.ru]оптимизация сайта блог[/url] .
stati o marketinge _askn
28 Oct 25 at 7:24 am
гидроизоляция подвала цена за м2 [url=gidroizolyaciya-cena-7.ru]гидроизоляция подвала цена за м2[/url] .
gidroizolyaciya cena_kzSi
28 Oct 25 at 7:25 am
купить диплом в норильске [url=https://rudik-diplom8.ru]купить диплом в норильске[/url] .
Diplomi_yzMt
28 Oct 25 at 7:26 am
купить диплом о высшем образовании с занесением в реестр [url=https://frei-diplom1.ru]купить диплом о высшем образовании с занесением в реестр[/url] .
Diplomi_ntOi
28 Oct 25 at 7:26 am
гидроизоляция подвала цена за м2 [url=https://gidroizolyaciya-cena-8.ru/]гидроизоляция подвала цена за м2[/url] .
gidroizolyaciya cena_cwKn
28 Oct 25 at 7:26 am
kraken сайт
кракен
Henryamerb
28 Oct 25 at 7:27 am