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!
Thank you for sharing your thoughts. I really appreciate
your efforts and I will be waiting for your next write ups thanks once again.
turkey visa for australian
4 Oct 25 at 11:27 pm
I do not even know how I ended up here, but I thought this post was good.
I don’t know who you are but definitely you’re going to a
famous blogger if you are not already 😉 Cheers!
игровые автоматы бесплатно онлайн без регистрации
4 Oct 25 at 11:29 pm
кухни от производителя спб [url=https://kuhni-spb-1.ru/]kuhni-spb-1.ru[/url] .
kyhni spb_ypmi
4 Oct 25 at 11:30 pm
This text is worth everyone’s attention. When can I find out more?
Megapolis cheats coins
4 Oct 25 at 11:31 pm
купить диплом в копейске [url=http://rudik-diplom7.ru/]купить диплом в копейске[/url] .
Diplomi_xzPl
4 Oct 25 at 11:32 pm
I don’t know if it’s just me or if perhaps everyone else experiencing problems with your blog.
It looks like some of the written text in your content are running off the screen.
Can someone else please comment and let me know if this is happening to them too?
This could be a problem with my browser because I’ve had this happen before.
Cheers
Meteor Profit Reseña
4 Oct 25 at 11:32 pm
войти 1win [url=https://www.1win5517.ru]войти 1win[/url]
1win_bzOl
4 Oct 25 at 11:35 pm
By Click Downloader ile YouTube’un yanı sıra Facebook,
Soundcloud, Instagram, Vimeo ve diğer birçok platformdan video indirebilirsiniz.
Video Indir.Com
4 Oct 25 at 11:35 pm
diwangdh77 – I like how well-organized the layout is throughout.
Travis Colly
4 Oct 25 at 11:35 pm
Приобрести MEF GASH SHIHSKI ALFA – ОТЗЫВЫ, ГАРАНТРР, КАЧЕСТВО
RodneyDof
4 Oct 25 at 11:36 pm
купить диплом в арзамасе [url=http://www.rudik-diplom4.ru]купить диплом в арзамасе[/url] .
Diplomi_ezOr
4 Oct 25 at 11:37 pm
Что включено на практике
Получить дополнительные сведения – [url=https://narkologicheskaya-klinika-odincovo0.ru/]narkologicheskaya-klinika-ceny[/url]
FidelDob
4 Oct 25 at 11:37 pm
купить аттестат [url=http://rudik-diplom8.ru]купить аттестат[/url] .
Diplomi_llMt
4 Oct 25 at 11:37 pm
купить диплом о среднем техническом образовании [url=http://educ-ua7.ru]http://educ-ua7.ru[/url] .
Diplomi_jtea
4 Oct 25 at 11:37 pm
купить диплом психолога [url=www.rudik-diplom2.ru]купить диплом психолога[/url] .
Diplomi_yzpi
4 Oct 25 at 11:38 pm
zzj186 – Everything functions properly, no visual bugs or page errors noticed.
Bell Biddie
4 Oct 25 at 11:38 pm
Fruit Splash AZ
ScottTem
4 Oct 25 at 11:39 pm
усиление углеволокном [url=dpcity.ru/usilenie-betona-uglevoloknom-fundamentov-svayami-i-gruntov-inektirovaniem-yuviks-grupp-spb/]dpcity.ru/usilenie-betona-uglevoloknom-fundamentov-svayami-i-gruntov-inektirovaniem-yuviks-grupp-spb/[/url] .
ysilenie yglevoloknom_boMt
4 Oct 25 at 11:40 pm
купить диплом о высшем образовании проведенный [url=http://frei-diplom4.ru/]купить диплом о высшем образовании проведенный[/url] .
Diplomi_hgOl
4 Oct 25 at 11:42 pm
купить диплом с занесением в реестр в москве [url=frei-diplom1.ru]купить диплом с занесением в реестр в москве[/url] .
Diplomi_ceOi
4 Oct 25 at 11:42 pm
Awesome! Its really awesome paragraph, I have got much
clear idea regarding from this paragraph.
اسکیما رویداد
4 Oct 25 at 11:43 pm
кухни на заказ питер [url=https://www.kuhni-spb-1.ru]https://www.kuhni-spb-1.ru[/url] .
kyhni spb_ycmi
4 Oct 25 at 11:47 pm
Мы помогаем при острых состояниях, связанных с алкоголем, и сопровождаем до устойчивой ремиссии. Детокс у нас — это не «одна капельница», а система мер: регидратация и коррекция электролитов, защита печени и ЖКТ, мягкая седативная поддержка по показаниям, контроль давления/пульса/сатурации/температуры, оценка сна и уровня тревоги. После стабилизации обсуждаем стратегию удержания результата: подготовку к кодированию (если показано), настройку поддерживающей терапии и реабилитационный блок.
Разобраться лучше – https://narkologicheskaya-klinika-mytishchi0.ru
PhillipSok
4 Oct 25 at 11:47 pm
купить диплом диспетчера [url=http://rudik-diplom4.ru/]купить диплом диспетчера[/url] .
Diplomi_kbOr
4 Oct 25 at 11:52 pm
кухни на заказ в спб [url=http://www.kuhni-spb-1.ru]http://www.kuhni-spb-1.ru[/url] .
kyhni spb_ccmi
4 Oct 25 at 11:53 pm
A seabed of shipwrecks
[url=https://rutordev.com]rutorforum at[/url]
The Great Lakes have the most shipwrecks per square mile among all bodies of water in the world, largely due to the high shipping traffic in the 19th century and the lake’s volatile weather. Researchers know about the wrecks because reporting any commercial ship that sails on the lakes is required; from the early 19th century to the 20th century, about 40,000 ships sailed the Great Lakes, Baillod said.
There are about 6,000 commercial vessels on the seabed of the Great Lakes, lost to storms or other issues. In Lake Michigan alone, there are over 200 shipwrecks waiting to be discovered, according to Baillod, who has created a database of these ships over the past three decades.
https://rutordev.com
rutor-24 at
Wrecks in the Great Lakes have been found since the 1960s, but in recent years the rate of these finds has accelerated greatly, in part due to media attention, clearer waters and better technology, Baillod said. Some wreck hunters and media outlets call this the golden age for shipwreck discoveries.
“There’s a lot more shipwreck awareness now on the Great Lakes, and people are looking down in the water at what’s on the bottom,” he added. Part of the reason it’s easier to see in the water is thanks to quagga mussels — an invasive species that was introduced in the 1990s. The mollusks have filtered most of the lakes, turning them from their old greenish hue, which allowed for only a few feet of visibility, to clear blue. Now, the lakes have visibility of up to 50 to 100 feet (15 to 30.5 meters), Baillod explained.
“Tourism has popped up around paddle boarding and kayaking, and these shipwrecks are visible from the surface because the water is so clear,” he added.
Related article
The wreckage of the Mary Rose at The Mary Rose Museum in Portsmouth, England.
A Tudor warship sank nearly 500 years ago. The bones of its crew reveal what life was like
And then there are advancements in technology. “Side-scan sonar used to cost $100,000 back in 1980,” he said. “The one we used to find this (shipwreck) was just over $10,000. They’ve really come down in price.”
The National Oceanographic and Atmospheric Administration, or NOAA, has a project in the works to map the bottom of the Great Lakes in high resolution by 2030. If the organization succeeds, all shipwrecks will be found, Baillod said.
In the meantime, Baillod said he hopes he and his team will continue to discover missing shipwrecks from his database in the coming years and bring along citizen scientists for the ride: “I keep looking, and I don’t doubt that we’ll keep finding.”
Wiltontus
4 Oct 25 at 11:53 pm
I was recommended this web site by my cousin.
I am not sure whether this post is written by him as no one else know such
detailed about my trouble. You are wonderful! Thanks!
اسکیما حق کپی رایت و لایسنس تصاویر
4 Oct 25 at 11:53 pm
Hi there! I could have sworn I’ve been to this
blog before but after checking through some of the post I realized it’s
new to me. Nonetheless, I’m definitely delighted I found it and I’ll be book-marking and checking back
frequently!
WhatsApp网页版
4 Oct 25 at 11:54 pm
95657777 – The site feels smooth and everything loaded fast without delay.
Myrtie Ducote
4 Oct 25 at 11:56 pm
купить диплом в октябрьском [url=http://www.rudik-diplom5.ru]купить диплом в октябрьском[/url] .
Diplomi_adma
4 Oct 25 at 11:58 pm
бк 1win сайт [url=http://1win5517.ru]бк 1win сайт[/url]
1win_ipOl
4 Oct 25 at 11:59 pm
сколько стоит купить диплом медсестры [url=https://www.frei-diplom14.ru]сколько стоит купить диплом медсестры[/url] .
Diplomi_vloi
5 Oct 25 at 12:00 am
I loved as much as you will receive carried out right here.
The sketch is tasteful, your authored subject matter stylish.
nonetheless, you command get bought an edginess over that
you wish be delivering the following. unwell unquestionably come more
formerly again as exactly the same nearly very often inside
case you shield this increase.
https://www.fiverr.com/s/m5Z6lr9
5 Oct 25 at 12:00 am
кухня на заказ спб [url=https://kuhni-spb-1.ru/]kuhni-spb-1.ru[/url] .
kyhni spb_xpmi
5 Oct 25 at 12:00 am
Приобрести MEF GASH SHIHSKI ALFA – ОТЗЫВЫ, ГАРАНТРР, КАЧЕСТВО
RodneyDof
5 Oct 25 at 12:01 am
Neon Capital
Michaelrow
5 Oct 25 at 12:05 am
I am in fact pleased to glance at this webpage posts which consists of
tons of helpful information, thanks for providing these statistics.
Yupoo Balenciaga
5 Oct 25 at 12:05 am
Fugly Pets играть в Казино Х
Matthewbox
5 Oct 25 at 12:06 am
Genuinely no matter if someone doesn’t know after
that its up to other visitors that they will assist, so here it takes place.
Packers and Movers Bangalore to Chandigarh
5 Oct 25 at 12:06 am
https://взятьзаймонлайн.рф/ Ваш сайт имеет систему резервного копирования данных, это надежно для 30 микрозаймы онлайн.
Ronaldder
5 Oct 25 at 12:06 am
Такой подход делает лечение предсказуемым: вы понимаете, что происходит сейчас, чего ждать завтра и как закрепить результат на горизонте недель и месяцев.
Подробнее тут – http://narkologicheskaya-klinika-podolsk0.ru
DonaldNus
5 Oct 25 at 12:08 am
купить диплом с реестром спб [url=https://www.frei-diplom4.ru]купить диплом с реестром спб[/url] .
Diplomi_teOl
5 Oct 25 at 12:09 am
melbet зеркало скачать [url=melbetofficialsite.ru]melbet зеркало скачать[/url] .
melbet_xgsa
5 Oct 25 at 12:09 am
усиление углеволокном [url=www.dpcity.ru/usilenie-betona-uglevoloknom-fundamentov-svayami-i-gruntov-inektirovaniem-yuviks-grupp-spb/]www.dpcity.ru/usilenie-betona-uglevoloknom-fundamentov-svayami-i-gruntov-inektirovaniem-yuviks-grupp-spb/[/url] .
ysilenie yglevoloknom_ynMt
5 Oct 25 at 12:10 am
купить диплом в бийске [url=rudik-diplom5.ru]купить диплом в бийске[/url] .
Diplomi_hjma
5 Oct 25 at 12:13 am
There’s certainly a lot to know about this subject. I like all
of the points you’ve made.
With thanks
5 Oct 25 at 12:13 am
большая кухня на заказ [url=https://kuhni-spb-1.ru/]https://kuhni-spb-1.ru/[/url] .
kyhni spb_uqmi
5 Oct 25 at 12:13 am
купить диплом машиниста [url=https://rudik-diplom3.ru]купить диплом машиниста[/url] .
Diplomi_uwei
5 Oct 25 at 12:14 am
Excited for $MTAUR coin’s role in personalizing characters—fancy outfits via tokens? Yes please. Presale’s low barrier ($10 min) opens it to everyone. Community events sound epic.
minotaurus ico
WilliamPargy
5 Oct 25 at 12:14 am
In Singapore’s competitive academic landscape, secondary school math tuition plays аn essential role in helping ʏour post-PSLE child grasp abstract concepts
еarly іn Secondary 1.
Power leh, Singapore’ѕ math excellence shines on tһe world stage
sіa!
Parents in Singapore, Singapore math tuition iѕ necessary foг supporting
math skills early. Secondary math tuition constructs
а positive attitude tоwards challenges. Through secondary 1 math tuition, ѕet theory becօmeѕ an exciting expedition fߋr your kid.
Ethical ᎪI uѕe in secondary 2 math tuition helps tutoring.
Secondary 2 math tuition leverages tools properly. Modern secondary 2 math tuition гemains ethical.
Secondary 2 math tuition designs integrity.
Carrying ᧐ut well in seconddary 3 math exams іs importɑnt, offered Օ-Levels’
distance. High marks makе it poѕsible fⲟr geometry shaping.
Success promotes neighborhood structure.
Singapore’ѕ education wisens secondary 4 exams ѡith AI.
Secpndary 4 math tuition problem adjusts. Τһis optimization improves Ο-Level.
Secondary 4 math tuition wisens.
Вeyond assessments, math serves аs an essential skill in exploding АI, critical for biometric security advancements.
Foster а genuine affection f᧐r mathematics and weave itѕ principles intо your daily real-ѡorld experiences t᧐ trսly excel.
Ꭲhe practice іs crucial for integrating feedback
fгom mock tests based ᧐n varioսs Singapore secondary
school papers.
Leveraging online math tuition е-learning systems enables
Singapore learners tⲟ collaborate οn groᥙp assignments,
enhancing оverall exam preparation.
Aiyoh leh, ⅾοn’t panic lah, your kid ready fоr secondary school,
support ԝithout pressure.
Interdisciplinary web ⅼinks in OMT’s lessons reveal math’ѕ versatility, sparking іnterest aand
inspiration fߋr test success.
Experience flexible knowing anytime, аnywhere tһrough OMT’s thoprough online e-learning platform,
including unlimited access tօ video lessons and interactive quizzes.
Ꭺs mathematics forms tһе bedrock of abstract thhought ɑnd importаnt analytical іn Singapore’s education ѕystem, expert math tuition οffers tһe tailored assistance required to tսrn difficulties
іnto accomplishments.
Ultimately, primary school math tuition іs imⲣortant for PSLE excellence, as it gears up trainees ԝith the tools to accomplish
leading bands ɑnd secure favored secondary school positionings.
Ꭰetermining and remedying сertain weak рoints, likе in probability or coordinate
geometry, mɑkes secondary tuition crucial for O Level excellence.
Structure confidence tһrough consistent support
in junior college math tuition minimizes test anxiousness, гesulting in much
better outcomes іn A Levels.
OMT establishes іtself apart with аn exclusive curriculum tһat extends MOE web c᧐ntent Ƅy consisting ᧐f enrichment activities focused ᧐n establishing mathematical instinct.
Taped sessions іn OMT’s system let yoᥙ rewind and replay lah, ensuring уou comprehend
еvery concept foг superior examination гesults.
Team math tuition іn Singapore cultivates peer learning,inspiring pupils tо press tougher fօr premium exam outcomes.
my hоmepage :: primary 4 math tuition
primary 4 math tuition
5 Oct 25 at 12:15 am