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!
ишимбайский нефтяной колледж купить диплом [url=www.frei-diplom12.ru/]www.frei-diplom12.ru/[/url] .
Diplomi_uyPt
22 Oct 25 at 4:24 pm
перевод медицинского заключения [url=telegra.ph/Medicinskij-perevod-tochnost-kak-vopros-zhizni-i-zdorovya-10-16]telegra.ph/Medicinskij-perevod-tochnost-kak-vopros-zhizni-i-zdorovya-10-16[/url] .
Medicinskii perevod_otEr
22 Oct 25 at 4:24 pm
купить диплом в твери [url=http://rudik-diplom7.ru/]купить диплом в твери[/url] .
Diplomi_lpPl
22 Oct 25 at 4:24 pm
купить диплом отзывы [url=www.rudik-diplom12.ru]купить диплом отзывы[/url] .
Diplomi_waPi
22 Oct 25 at 4:25 pm
переводы научно технической технической литературы [url=http://teletype.in/@alexd78/HN462R01hzy/]http://teletype.in/@alexd78/HN462R01hzy/[/url] .
Vidi perevodov v buro Perevod i Pravo_itst
22 Oct 25 at 4:26 pm
learnshareconnect.shop – Content feels genuine and helpful, not just fluff, which I appreciate.
Diego Sures
22 Oct 25 at 4:26 pm
купить диплом в ишимбае [url=https://rudik-diplom2.ru/]https://rudik-diplom2.ru/[/url] .
Diplomi_lnpi
22 Oct 25 at 4:29 pm
Промокод 1xBet при регистрации. Промо-код встречается на просторах сети достаточно часто. Букмекер использует его для привлечения новых игроков в индустрию ставок, но преимущество предоставляется и новому игроку. После того как он совершит первый депозит, на его бонусный счёт поступит аналогичная сумма, до 32500 рублей. 1xbet бездепозитный бонус промокод Данный вид бонус-кода также популярен в поиске. Указывать его надо в купоне для совершения ставки. Промокод 1xBet на ставку практически невозможно найти в бесплатном доступе. Он вручается игрокам индивидуально.К примеру, компания промокодов. В данном разделе подробно расписан процесс получения.
BrianAcina
22 Oct 25 at 4:29 pm
виды технического перевода [url=dzen.ru/a/aPFFa3ZMdGVq1wVQ]dzen.ru/a/aPFFa3ZMdGVq1wVQ[/url] .
Tehnicheskii perevod_zsml
22 Oct 25 at 4:30 pm
купить диплом в березниках [url=http://rudik-diplom7.ru]купить диплом в березниках[/url] .
Diplomi_jnPl
22 Oct 25 at 4:31 pm
Как купить Фенибут в Гаврилов-Яме?Посмотрите сайт https://framboises-bakery.ru
– нормальные цены, обещают быструю доставку. Кто-нибудь пробовал у них? Как с чистотой товар?
Stevenref
22 Oct 25 at 4:31 pm
переводы научно технической технической литературы [url=www.teletype.in/@alexd78/HN462R01hzy/]www.teletype.in/@alexd78/HN462R01hzy/[/url] .
Vidi perevodov v buro Perevod i Pravo_eest
22 Oct 25 at 4:32 pm
сео продвижение москва [url=http://seo-prodvizhenie-reiting-kompanij.ru]сео продвижение москва[/url] .
seo prodvijenie reiting kompanii_fhst
22 Oct 25 at 4:34 pm
My spouse and I absolutely love your blog and find many of your post’s to be
exactly what I’m looking for. Would you offer guest writers
to write content for you personally? I wouldn’t mind publishing
a post or elaborating on a number of the subjects you
write with regards to here. Again, awesome site!
buôn bán nội tạng
22 Oct 25 at 4:34 pm
Listen, goodness, famous schools feature graduate events,
linking children t᧐ advisors іn high-flying professions.
Parents, fearful ᧐f losing mode full lah, leading primaries prepare fоr country-wide assessments,
guaranteeing effortless ϲhanges to secs.
Do not take lightly lah, combine a ɡood primary school alongside arithmetic proficiency іn oгder to assure superior PSLE
scores аs well as effortless transitions.
Aiyo, mіnus strong math ⅾuring primary school, еven prestigious school children mɑy struggle witһ next-level calculations, tһerefore
cultivate tһat now leh.
Oi oi, Singapore moms аnd dads, math remаins probaƅly the most іmportant primary discipline, fostering imagination fߋr issue-resolving tο groundbreaking professions.
Eh eh, steady pom рi pi, arithmetic proves ᧐ne of tһе leading topics ɑt primary school, building base іn A-Level
һigher calculations.
Ιn addition to institution amenities, emphasize upon math ffor ѕtop frequent errors
sսch as sloppy mistakes during assessments.
Benefit Lay Garden Primary School ρrovides a nurturing environment tһɑt motivates
curiosity аnd growth.
Devoted instructors аnd differed programs assist trainees establish skills fօr lifelong success.
Edgefield Primary School supplies ɑ supportive neighborhood fοr development.
Ԝith diverse programs, іt nurtures talents efficiently.
It’s ɑ solid choice fօr holistic development.
ᒪooк at my web ρage … Hillgrove Secondary School
Hillgrove Secondary School
22 Oct 25 at 4:35 pm
Viagra kaufen Apotheke Preis: Medi Vertraut – sichere Online-Apotheke Deutschland
AnthonySep
22 Oct 25 at 4:35 pm
купить диплом в ачинске [url=www.rudik-diplom7.ru]купить диплом в ачинске[/url] .
Diplomi_oyPl
22 Oct 25 at 4:36 pm
купить аттестаты за 11 [url=http://rudik-diplom2.ru/]купить аттестаты за 11[/url] .
Diplomi_kupi
22 Oct 25 at 4:37 pm
Sildenafil online reviews: Viagra generic price comparison – Blue Peak Meds
WilliamUnjup
22 Oct 25 at 4:37 pm
купить диплом инженера электрика [url=http://rudik-diplom12.ru]купить диплом инженера электрика[/url] .
Diplomi_eoPi
22 Oct 25 at 4:37 pm
медицинский перевод с английского [url=https://www.telegra.ph/Medicinskij-perevod-tochnost-kak-vopros-zhizni-i-zdorovya-10-16]https://www.telegra.ph/Medicinskij-perevod-tochnost-kak-vopros-zhizni-i-zdorovya-10-16[/url] .
Medicinskii perevod_zhEr
22 Oct 25 at 4:37 pm
Play The Password Game online in Canada! Test your creativity and problem-solving skills as you craft secure passwords with fun, unique challenges. Perfect for puzzle enthusiasts: official Password Game website
GabrielLyday
22 Oct 25 at 4:38 pm
В результате извержения вершина вулкана провалилась,
образовав кальдеру — огромную круглую впадину с длиной окружности 150 км[3].
вулкан играть
22 Oct 25 at 4:40 pm
https://www.diigo.com/item/note/8wxs2/ym9n?k=586db6cae46fb6aff02973e804caee73
JeffreyHew
22 Oct 25 at 4:40 pm
купить диплом о высшем образовании [url=www.rudik-diplom2.ru]купить диплом о высшем образовании[/url] .
Diplomi_ospi
22 Oct 25 at 4:42 pm
что такое технические перевод [url=https://dzen.ru/a/aPFFa3ZMdGVq1wVQ]https://dzen.ru/a/aPFFa3ZMdGVq1wVQ[/url] .
Tehnicheskii perevod_mdml
22 Oct 25 at 4:44 pm
I don’t know whether it’s just me or if everyone else experiencing issues with your
site. It appears as if some of the written text
on your posts are running off the screen. Can someone
else please comment and let me know if this is happening to them too?
This may be a problem with my internet browser because I’ve
had this happen before. Appreciate it
malaysia solar water heater
22 Oct 25 at 4:44 pm
медицинский перевод на английский [url=www.telegra.ph/Medicinskij-perevod-tochnost-kak-vopros-zhizni-i-zdorovya-10-16/]www.telegra.ph/Medicinskij-perevod-tochnost-kak-vopros-zhizni-i-zdorovya-10-16/[/url] .
Medicinskii perevod_uuEr
22 Oct 25 at 4:46 pm
If some one wishes to be updated with hottest technologies after
that he must be pay a quick visit this web site and be up
to date everyday.
joycasino регистрация
22 Oct 25 at 4:47 pm
You should take part in a contest for one of
the greatest sites on the internet. I most certainly will recommend this website!
Appreciate it
22 Oct 25 at 4:49 pm
Great beat ! I would like to apprentice while you
amend your site, how could i subscribe for a blog web site?
The account helped me a acceptable deal. I
had been tiny bit acquainted of this your broadcast offered bright
clear idea
Magnumator
22 Oct 25 at 4:51 pm
http://bluepeakmeds.com/# Sildenafil online reviews
MichaelZow
22 Oct 25 at 4:51 pm
купить диплом в буйнакске [url=https://www.rudik-diplom7.ru]https://www.rudik-diplom7.ru[/url] .
Diplomi_chPl
22 Oct 25 at 4:53 pm
технический перевод информация [url=www.dzen.ru/a/aPFFa3ZMdGVq1wVQ]www.dzen.ru/a/aPFFa3ZMdGVq1wVQ[/url] .
Tehnicheskii perevod_qoml
22 Oct 25 at 4:53 pm
купить диплом техникума с занесением в реестр [url=www.frei-diplom7.ru/]купить диплом техникума с занесением в реестр[/url] .
Diplomi_uyei
22 Oct 25 at 4:53 pm
купить диплом в подольске [url=http://www.rudik-diplom12.ru]купить диплом в подольске[/url] .
Diplomi_jrPi
22 Oct 25 at 4:54 pm
If you are looking for trusted sites in the USA, then this is definitely worth checking out. Explore the full details via the attached link:
best online casino USA
JeffreyEdund
22 Oct 25 at 4:55 pm
перевод медицинских терминов [url=http://www.teletype.in/@alexd78/HN462R01hzy]http://www.teletype.in/@alexd78/HN462R01hzy[/url] .
Vidi perevodov v buro Perevod i Pravo_lkst
22 Oct 25 at 4:56 pm
An outstanding share! I have just forwarded this onto a co-worker who
has been conducting a little research on this. And he in fact ordered me breakfast due
to the fact that I found it for him… lol. So
let me reword this…. Thank YOU for the meal!! But yeah,
thanx for spending the time to discuss this subject here on your internet site.
slot gacor
22 Oct 25 at 4:58 pm
Aiyah, steady pom рі pi hor, excellent primary educates culinary,
igniting chef business professions.
Listen ᥙp, top institutions incorporate meditation, boosting
attention fоr demanding job positions.
Вesides beyond school facilities, concentrate on mathematics іn oгԀeг to prevent common pitfalls
ѕuch as careless errors іn exams.
Goodness, rеgardless tһough establishment proves atas,
mathematics acts ⅼike the critical topic fοr developing confidence гegarding numberѕ.
Hey hey, Singapore folks, mathematics іs probably the most essential primary topic, promoting innovation іn challenge-tackling іn innovative jobs.
Guardians, fear tһe disparity hor, mathematics foundation rеmains vital duгing primary
school tо grasping figures, vital f᧐r modern digital ѕystem.
In adɗition tߋ institution amenities, focus on arithmetic fοr stop frequent mistakes
including careless blunders іn assessments.
Maris Stella Ꮋigh School (Primary Ѕection) provides a faith-centered education fоr young boys.
Ꮤith strenuous academics, іt prepares students f᧐r
leadership.
West Ꮩiew Primary School оffers scenic learning ԝith quality teaching.
Ꭲhe school develops strong structures.
Moms аnd dads value itѕ ᴡell balanced curriculum.
My web page … Sembawang Secondary School (Leora)
Leora
22 Oct 25 at 4:58 pm
куплю диплом высшего образования [url=http://rudik-diplom3.ru/]куплю диплом высшего образования[/url] .
Diplomi_ahei
22 Oct 25 at 4:58 pm
особенности медицинского перевода [url=https://telegra.ph/Medicinskij-perevod-tochnost-kak-vopros-zhizni-i-zdorovya-10-16]https://telegra.ph/Medicinskij-perevod-tochnost-kak-vopros-zhizni-i-zdorovya-10-16[/url] .
Medicinskii perevod_sgEr
22 Oct 25 at 5:02 pm
Why people still use to read news papers when in this technological globe everything is existing on net?
site
22 Oct 25 at 5:03 pm
Le code promo est supprime : entrez-le dans le champ « Code promo » et reclamez un bonus de bienvenue de 100% jusqu’a 130€, a utiliser dans les paris sportifs. Inscrivez-vous sur 1xBet ou via l’application mobile. Apres votre premier depot, vous activerez le code bonus. L’offre est valable pour toute l’annee 2026, et le bonus doit etre mise dans les 30 jours. Vous pouvez trouver le code promo sur ce lien — https://fgvjr.com/pgs/code_promo_163.html.
Marvinspaft
22 Oct 25 at 5:05 pm
Excited about Minotaurus presale’s DeFi simplicity. $MTAUR’s appreciation potential high. Whimsical mazes fun.
minotaurus ico
WilliamPargy
22 Oct 25 at 5:05 pm
everydayvaluecorner.shop – Affordable, reliable, and consistent every single time I order.
Ramona Starnauld
22 Oct 25 at 5:05 pm
бюро переводов в Москве [url=https://teletype.in/@alexd78/HN462R01hzy/]https://teletype.in/@alexd78/HN462R01hzy/[/url] .
Vidi perevodov v buro Perevod i Pravo_zqst
22 Oct 25 at 5:06 pm
купить диплом сварщика [url=https://www.rudik-diplom3.ru]купить диплом сварщика[/url] .
Diplomi_zmei
22 Oct 25 at 5:06 pm
купить диплом моряка [url=https://rudik-diplom7.ru]купить диплом моряка[/url] .
Diplomi_fuPl
22 Oct 25 at 5:07 pm
Minotaurus ICO is targeting $6.4M, and with current traction, it’ll smash it. $MTAUR’s DeFi access empowers users without complexity. Referral rewards have me spreading the word.
mtaur coin
WilliamPargy
22 Oct 25 at 5:08 pm