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!
1win azerbaycan rəsmisi [url=https://www.1win5004.com]https://www.1win5004.com[/url]
1win_lboi
13 Oct 25 at 3:03 am
The $MTAUR ICO partnerships boost visibility. Token conversions practical. Hype building.
minotaurus coin
WilliamPargy
13 Oct 25 at 3:03 am
Tamiflu verkurzt die Dauer von Grippeinfektionen. Fruhzeitige Einnahme ist fur die Wirkung entscheidend.
Z-Pak
ThomasInvag
13 Oct 25 at 3:04 am
купить диплом с проводкой [url=frei-diplom2.ru]купить диплом с проводкой[/url] .
Diplomi_zlEa
13 Oct 25 at 3:05 am
By linking math to innovative tasks, OMT stirs սp an enthusiasm in students, encouraging tһem to ѡelcome tһe subject аnd strive fоr
examination mastery.
Enroll tⲟԀay in OMT’s standalone е-learning programs and watch your grades soar through
unlimited access tօ top quality, syllabus-aligned content.
Aѕ math forms tһe bedrock of abstract thоught аnd critical рroblem-solving in Singapore’ѕ
education ѕystem, professional math tuition supplies tһe individualized guidance neсessary to tսrn obstacles intⲟ victories.
Enrolling іn primary school school math tuition еarly fosters confidence,
decreasing stress аnd anxiety for PSLE takers ԝһo deal witһ high-stakes concerns
ⲟn speed, distance, ɑnd tіme.
Ԝith the O Level mathematics curriculum occasionally progressing, tuition maintains students upgraded օn changеѕ, ensuring thеy aге ᴡell-prepared for current layouts.
In an affordable Singaporean education ɑnd learning system, junior college
math tuition ɡives pupils tһe edge to attain һigh qualities essential fοr university admissions.
OMT establishes іtself apart with an exclusive curriculum
tһat prolongs MOE web ϲontent by including enrichment activities intended аt creating
mathematical intuition.
Ⲛo requirement tߋ take a trip, just log in from
hοme leh, saving tіme to examine eѵen morе and push youг math qualities greаter.
Tuition exposes trainees tօo diverse concern kinds, widening tһeir readiness foг unforeseeable Singapore mathematics
tests.
Herre іs my web site :: math tuition singapore
math tuition singapore
13 Oct 25 at 3:05 am
https://masterieltsonline.ru
RandyEluse
13 Oct 25 at 3:05 am
купить дипломы о высшем образовании цена [url=https://www.rudik-diplom2.ru]купить дипломы о высшем образовании цена[/url] .
Diplomi_espi
13 Oct 25 at 3:06 am
купить диплом медсестры [url=https://frei-diplom15.ru]купить диплом медсестры[/url] .
Diplomi_bloi
13 Oct 25 at 3:07 am
My family members every time say that I am killing
my time here at web, but I know I am getting familiarity everyday by reading such good posts.
Zlaté batérie
13 Oct 25 at 3:09 am
1win idman mərcləri [url=http://1win5004.com/]http://1win5004.com/[/url]
1win_kaoi
13 Oct 25 at 3:10 am
Купить диплом о высшем образовании поспособствуем. Купить диплом тренера – [url=http://diplomybox.com/diplom-trenera/]diplomybox.com/diplom-trenera[/url]
Cazrdnf
13 Oct 25 at 3:13 am
Scientists discovered something alarming seeping out from beneath the ocean around Antarctica
[url=https://dzen.ru/a/YaF3ljBc61y4BXkz]раз анальный секс[/url]
Planet-heating methane is escaping from cracks in the Antarctic seabed as the region warms, with new seeps being discovered at an “astonishing rate,” scientists have found, raising fears that future global warming predictions may have been underestimated.
Huge amounts of methane lie in reservoirs that have formed over millennia beneath the seafloor around the world. This invisible, climate-polluting gas can escape into the water through fissures in the sea floor, often revealing itself with a stream of bubbles weaving their way up to the ocean surface.
https://pikabu.ru/story/tsentrobank_priznal_kholding_life_is_good_ltd_kompaniey_s_priznakami_finansovoy_piramidyi_8626208
раз анальный секс
Relatively little is known about these underwater seeps, how they work, how many there are, and how much methane reaches the atmosphere versus how much is eaten by methane-munching microbes living beneath the ocean.
But scientists are keen to better understand them, as this super-polluting gas traps around 80 times more heat than carbon dioxide in its first 20 years in the atmosphere.
Methane seeps in Antarctica are among the least understood on the planet, so a team of international scientists set out to find them. They used a combination of ship-based acoustic surveys, remotely operated vehicles and divers to sample a range of sites in the Ross Sea, a bay in Antarctica’s Southern Ocean, at depths between 16 and 790 feet.
What they found surprised them. They identified more than 40 methane seeps in the shallow water of the Ross Sea, according to the study published this month in Nature Communications.
Bubbles rising from a methane seep at Cape Evans, Antarctica. Leigh Tate, Earth Sciences New Zealand
Many of the seeps were found at sites that had been repeatedly studied before, suggesting they were new. This may indicate a “fundamental shift” in the methane released in the region, according to the report.
Methane seeps are relatively common globally, but previously there was only one confirmed active seep in the Antarctic, said Sarah Seabrook, a report author and a marine scientist at Earth Sciences New Zealand, a research organization. “Something that was thought to be rare is now seemingly becoming widespread,” she told CNN.
Every seep they discovered was accompanied by an “immediate excitement” that was “quickly replaced with anxiety and concern,” Seabrook said.
The fear is these seeps could rapidly transfer methane into the atmosphere, making them a source of planet-heating pollution that is not currently factored into future climate change predictions.
The scientists are also concerned the methane could have cascading impacts on marine life.
DonaldCix
13 Oct 25 at 3:14 am
купить диплом в чайковском [url=www.rudik-diplom2.ru/]купить диплом в чайковском[/url] .
Diplomi_tjpi
13 Oct 25 at 3:15 am
купить диплом с проводкой [url=frei-diplom3.ru]купить диплом с проводкой[/url] .
Diplomi_vtKt
13 Oct 25 at 3:15 am
купить диплом техникума ссср в майкопе [url=www.frei-diplom8.ru]купить диплом техникума ссср в майкопе[/url] .
Diplomi_ytsr
13 Oct 25 at 3:15 am
сайт трипскан
WillieCot
13 Oct 25 at 3:18 am
купить диплом в клинцах [url=https://rudik-diplom7.ru/]купить диплом в клинцах[/url] .
Diplomi_syPl
13 Oct 25 at 3:18 am
диплом колледж купить [url=https://frei-diplom9.ru/]https://frei-diplom9.ru/[/url] .
Diplomi_cyea
13 Oct 25 at 3:19 am
I know this if off topic but I’m looking into starting my own blog and was wondering what all is needed to get set
up? I’m assuming having a blog like yours would cost a pretty penny?
I’m not very web smart so I’m not 100% positive.
Any tips or advice would be greatly appreciated. Appreciate
it
kra47
13 Oct 25 at 3:20 am
http://amoxicareonline.com/# cheap amoxicillin
Raymondspemn
13 Oct 25 at 3:22 am
купить диплом техникума в украине старого образца [url=https://frei-diplom8.ru]купить диплом техникума в украине старого образца[/url] .
Diplomi_cisr
13 Oct 25 at 3:24 am
диплом купить с занесением в реестр [url=http://frei-diplom3.ru]диплом купить с занесением в реестр[/url] .
Diplomi_fmKt
13 Oct 25 at 3:25 am
Ich bin beeindruckt von SpinBetter Casino, es fuhlt sich an wie ein Strudel aus Freude. Das Angebot an Spielen ist phanomenal, mit immersiven Live-Sessions. Die Agenten sind blitzschnell, bietet klare Losungen. Die Auszahlungen sind ultraschnell, ab und an die Offers konnten gro?zugiger ausfallen. Global gesehen, SpinBetter Casino ist absolut empfehlenswert fur Casino-Liebhaber ! Au?erdem die Interface ist intuitiv und modern, was jede Session noch besser macht. Hervorzuheben ist die schnellen Einzahlungen, die Vertrauen schaffen.
spinbettercasino.de|
Miscusimerle3zef
13 Oct 25 at 3:28 am
купить диплом с занесением в реестр москва [url=www.frei-diplom3.ru/]купить диплом с занесением в реестр москва[/url] .
Diplomi_mvKt
13 Oct 25 at 3:30 am
медсестра которая купила диплом врача [url=frei-diplom14.ru]frei-diplom14.ru[/url] .
Diplomi_aioi
13 Oct 25 at 3:31 am
купить диплом с занесением в реестр [url=www.frei-diplom1.ru/]купить диплом с занесением в реестр[/url] .
Diplomi_cmOi
13 Oct 25 at 3:31 am
https://en-as.ru
RandyEluse
13 Oct 25 at 3:32 am
купить диплом московского колледжа [url=https://frei-diplom9.ru/]https://frei-diplom9.ru/[/url] .
Diplomi_cfea
13 Oct 25 at 3:34 am
Kaizenaire.cоm stands aѕ Singapore’ѕ utmost
location f᧐r aggregating unsurpassable deals,
рrice cuts,and amazing occasions tһroughout preferred firms.
Ꮤith varied retail options, Singaapore іs a
buyer’s paradise ԝhere promotions қeep deal-savvy
Singaporeans satisfied.
Coffee shop hopping ɑcross stylish аreas delights coffee-loving Singaporeans, ɑnd remember t᧐ stay
updated on Singapore’ѕ newеѕt promotions аnd
shopping deals.
Dzojchen supplies deluxe menswear ѡith Eastwrn ɑffects,
enjoyed Ƅy fіne-tuned Singaporeans fоr their innovative customizing.
In Ԍood Company supplies minimal women’s apparel leh, favored Ьy Singaporeans for
tһeir classic items ɑnd flexible closets ⲟne.
Suntory refreshes witһ teas аnd waters, preferred foг premium Japanese beverages
іn ease stores.
Singaporeans enjoy deals гight, ѕo see Kaizenaire.ⅽom daily lah,
filled ԝith shopping deals tһat maқе you shiok.
Visit mү ⲣage – economist sugscription promotions (maps.google.ae)
maps.google.ae
13 Oct 25 at 3:36 am
купить диплом стоматолога [url=https://rudik-diplom7.ru]купить диплом стоматолога[/url] .
Diplomi_yvPl
13 Oct 25 at 3:39 am
купить диплом с занесением в реестр в мурманске [url=https://frei-diplom1.ru/]купить диплом с занесением в реестр в мурманске[/url] .
Diplomi_vxOi
13 Oct 25 at 3:41 am
歡迎來到 DAGA 88 香港 – 您的勝利,全數支付。享受豐厚獎金,玩刺激遊戲,體驗公平舒適的線上博彩。立即註冊!
DAGA 88 香港 – 您的勝利,全數支付
13 Oct 25 at 3:42 am
Je suis completement fou de Locowin Casino, on ressent une vibe delirante. Les options sont incroyablement vastes, incluant des paris sportifs palpitants. Doublement des depots jusqu’a 1850 €. L’assistance est efficace et pro, toujours pret a aider. Les gains arrivent sans delai, parfois quelques tours gratuits en plus seraient cool. En resume, Locowin Casino vaut largement le detour pour ceux qui aiment parier en crypto ! Ajoutons que l’interface est intuitive et stylee, ajoute une touche de confort. Un plus non negligeable les evenements communautaires engageants, assure des transactions fiables.
Locowin|
CrazySpinQ4zef
13 Oct 25 at 3:43 am
где купить диплом техникума кого [url=frei-diplom9.ru]где купить диплом техникума кого[/url] .
Diplomi_hgea
13 Oct 25 at 3:44 am
купить диплом в муроме [url=http://rudik-diplom7.ru/]купить диплом в муроме[/url] .
Diplomi_mpPl
13 Oct 25 at 3:46 am
купить диплом с реестром [url=frei-diplom1.ru]купить диплом с реестром[/url] .
Diplomi_koOi
13 Oct 25 at 3:46 am
When some one searches for his required thing, therefore he/she needs to be available that in detail, so that thing is maintained over here.
situs togel
13 Oct 25 at 3:49 am
диплом внесенный в реестр купить [url=www.frei-diplom2.ru]диплом внесенный в реестр купить[/url] .
Diplomi_cvEa
13 Oct 25 at 3:50 am
1win şikayətlər [url=https://1win5004.com/]https://1win5004.com/[/url]
1win_iboi
13 Oct 25 at 3:54 am
Voltaren wird bei Gelenkschmerzen eingesetzt. Topische Anwendungen sind oft sicherer als Tabletten.
Velban
ThomasInvag
13 Oct 25 at 3:55 am
купить диплом техникума в молдове [url=www.frei-diplom9.ru/]купить диплом техникума в молдове[/url] .
Diplomi_cqea
13 Oct 25 at 3:56 am
купить диплом с реестром киев [url=frei-diplom3.ru]frei-diplom3.ru[/url] .
Diplomi_awKt
13 Oct 25 at 3:57 am
купить диплом с проводкой одной [url=http://frei-diplom2.ru/]купить диплом с проводкой одной[/url] .
Diplomi_xkEa
13 Oct 25 at 3:59 am
https://killjack.ru
RandyEluse
13 Oct 25 at 3:59 am
куплю диплом младшей медсестры [url=http://frei-diplom14.ru]http://frei-diplom14.ru[/url] .
Diplomi_xtoi
13 Oct 25 at 3:59 am
купить диплом в ухте [url=http://rudik-diplom2.ru/]купить диплом в ухте[/url] .
Diplomi_mhpi
13 Oct 25 at 4:03 am
I believe that is one of the such a lot vital information for me.
And i am glad reading your article. However wanna remark on some general issues, The web site taste is perfect, the articles is actually nice : D.
Just right task, cheers
khudokormov igor vyacheslavovich
13 Oct 25 at 4:03 am
как купить легальный диплом [url=http://frei-diplom2.ru]http://frei-diplom2.ru[/url] .
Diplomi_cfEa
13 Oct 25 at 4:05 am
broadcast channel
Keithwebra
13 Oct 25 at 4:08 am
I value the content you publish on 1win India.
Thank you!
1win India platform
1win India platform
13 Oct 25 at 4:08 am