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=https://vyvod-iz-zapoya-v-stacionare-samara16.ru/]вывод из запоя клиника[/url]
Pablotug
30 Aug 25 at 1:04 pm
Zombie Rabbit Invasion играть в Монро
Briannot
30 Aug 25 at 1:07 pm
где купить аттестат за 11 класс в челябинске [url=https://www.arus-diplom23.ru]где купить аттестат за 11 класс в челябинске[/url] .
Diplomi_ojol
30 Aug 25 at 1:09 pm
На Kinobadi собраны самые ожидаемые премьеры года: от масштабных блокбастеров до авторского кино, которое уже на слуху у фестивалей. Удобные подборки, актуальные рейтинги и трейлеры помогут быстро выбрать, что смотреть сегодня вечером или запланировать поход в кино. Свежие обновления, карточки фильмов с описанием и датами релизов, а также рекомендации по настроению экономят время и не дают пропустить громкие новинки. Смотрите топ 2025 по ссылке: https://kinobadi.mom/film/top-2025.html
Ceqycrdcounk
30 Aug 25 at 1:11 pm
casino online sicuri con Starburst: giocare da mobile a Starburst – migliori casino online con Starburst
Miltondep
30 Aug 25 at 1:12 pm
Близкий человек в запое? Не ждите ухудшения. Обратитесь в клинику — здесь проведут профессиональный вывод из запоя с последующим восстановлением организма.
Изучить вопрос глубже – [url=https://vyvod-iz-zapoya-v-stacionare-samara15.ru/]вывод из запоя дешево[/url]
Michaelamoma
30 Aug 25 at 1:15 pm
купить медицинский диплом с занесением в реестр [url=http://arus-diplom33.ru]купить медицинский диплом с занесением в реестр[/url] .
Priobresti diplom instityta!_qqoi
30 Aug 25 at 1:15 pm
What we’re covering
• Zelensky in Washington: European leaders will join Ukrainian President Volodymyr Zelensky at the White House, as he meets with US President Donald Trump this afternoon. Trump said Zelensky must agree to some of Russia’s conditions — including that Ukraine cede Crimea and agree never to join NATO — for the war to end.
[url=https://kraken33-at.com]kra36[/url]
• Potential security guarantees: At last week’s summit with Trump, Russian President Vladimir Putin agreed to allow security guarantees for Ukraine and made concessions on “land swaps” as part of a potential peace deal, US envoy Steve Witkoff told CNN. Zelensky suggested that such guarantees would need to be stronger than those that “didn’t work” in the past. Russia has yet to mention such agreements.
[url=https://kra36.net]kra36[/url]
• On the ground: Zelensky condemned Russia’s latest strikes across Ukraine, which killed at least 10 people, saying the Kremlin intends to “humiliate diplomatic efforts” and underscores “why reliable security guarantees are required.”
kra40 at
https://kra36at.com
RichardJek
30 Aug 25 at 1:17 pm
http://1wbook.com/# migliori casino online con Book of Ra
Alfredrew
30 Aug 25 at 1:17 pm
Магазин тут! Отзывы, Качество. kokain gash mefedron alfa-pvp
JamesCic
30 Aug 25 at 1:18 pm
I visited various web sites except the audio feature for audio songs present at this web page is truly wonderful.
what does a vape rash look like
30 Aug 25 at 1:19 pm
купить диплом украины с занесением в реестр [url=http://arus-diplom31.ru]http://arus-diplom31.ru[/url] .
Priobresti diplom VYZa!_qxOl
30 Aug 25 at 1:21 pm
можно ли купить аттестат за 11 [url=https://arus-diplom25.ru]https://arus-diplom25.ru[/url] .
Diplomi_tjot
30 Aug 25 at 1:21 pm
https://1wbook.shop/# Book of Ra Deluxe slot online Italia
Alfredrew
30 Aug 25 at 1:22 pm
jackpot e vincite su Starburst Italia: bonus di benvenuto per Starburst – casino online sicuri con Starburst
Miltondep
30 Aug 25 at 1:24 pm
Wow that was odd. I just wrote an incredibly long comment but after I clicked submit my comment didn’t show
up. Grrrr… well I’m not writing all that over again. Anyhow, just wanted to say
wonderful blog!
bandar toto slot
30 Aug 25 at 1:24 pm
Rainbet Casino is an international online gambling
platform operated by RBGAMING N.V. under a Curaçao license.
The site focuses on cryptocurrency payments and offers slots, live casino,
and its own provably fair games.
Rainbet Australia
30 Aug 25 at 1:31 pm
Среди основных задач клиники выделяются помощь людям, страдающим от хронического алкоголизма, наркозависимости, игромании и других расстройств. Мы осознаём, что каждый случай уникален, и подходим к каждому пациенту индивидуально, предлагая персонализированные программы лечения, учитывающие все аспекты его состояния. Основное внимание уделяется не только физическому, но и психологическому состоянию пациента, что позволяет более эффективно преодолевать зависимость.
Подробнее – [url=https://alko-konsultaciya.ru/]вывод из запоя капельница смоленск[/url]
Andrewwerie
30 Aug 25 at 1:34 pm
Keren artikel ini!
Pembahasan tentang situs taruhan bola resmi dan situs resmi
taruhan bola sangat informatif.
Saya sendiri sering menggunakan bola88 agen judi bola resmi serta situs taruhan terpercaya
untuk taruhanbola.
Selain itu, saya juga mencoba situs resmi taruhan bola online seperti idnscore,
sbobet, sbobet88, dan sarangsbobet.
Update score bola dari idnscore login, link sbobet, hingga
sbobet88 login sangat membantu saya.
Mix parlay, parlay88 login, serta idnscore 808 live juga membuat permainan bola online semakin seru.
Bermain di situs bola terpercaya, agen bola, situs bola live,
hingga judi bola online memberikan pengalaman berbeda.
Tidak ketinggalan situs bola online, esbobet, situs parlay, judi
bola terpercaya, dan situs judi bola terbesar yang makin populer.
Saya juga suka mencoba link judi bola, judi bola parlay, situs judi terbesar,
parlay 88, agen sbobet, dan linksbobet.
Dan tentu saja, kubet, kubet login, kubet indonesia, kubet link alternatif, serta kubet
login alternatif adalah platform andalan banyak pemain.
Terima kasih sudah berbagi info ini, cocok
sekali untuk pecinta judi bola online dan taruhanbola.
situs resmi taruhan bola online
30 Aug 25 at 1:36 pm
Attractive part of content. I just stumbled upon your site and in accession capital to
say that I get actually enjoyed account your
weblog posts. Any way I’ll be subscribing on your augment or even I success you get right of entry to persistently rapidly.
selling weed
30 Aug 25 at 1:38 pm
garuda888 game slot RTP tinggi: situs judi online resmi Indonesia – agen garuda888 bonus new member
Ramonatowl
30 Aug 25 at 1:41 pm
Приобрести MEF MEFEDRON GASH ALFA KOKAIN
JamesCic
30 Aug 25 at 1:41 pm
“LungExpand Pro looks like a really helpful supplement
for supporting stronger lungs and easier breathing. I like that it’s focused on natural ingredients to improve oxygen flow and
overall respiratory health. Seems like a great choice for anyone who wants to boost their lung capacity and feel more energized
daily.
LungExpand Pro
30 Aug 25 at 1:43 pm
Extreme heat is a killer. A recent heat wave shows how much more deadly it’s becoming
[url=https://tripscan.xyz]трип скан[/url]
Extreme heat is a killer and its impact is becoming far, far deadlier as the human-caused climate crisis supercharges temperatures, according to a new study, which estimates global warming tripled the number of deaths in the recent European heat wave.
For more than a week, temperatures in many parts of Europe spiked above 100 degrees Fahrenheit. Tourist attractions closed, wildfires ripped through several countries, and people struggled to cope on a continent where air conditioning is rare.
https://tripscan.xyz
трипскан сайт
The outcome was deadly. Thousands of people are estimated to have lost their lives, according to a first-of-its-kind rapid analysis study published Wednesday.
A team of researchers, led by Imperial College London and the London School of Hygiene and Tropical Medicine, looked at 10 days of extreme heat between June 23 and July 2 across 12 European cities, including London, Paris, Athens, Madrid and Rome.
They used historical weather data to calculate how intense the heat would have been if humans had not burned fossil fuels and warmed the world by 1.3 degrees Celsius. They found climate change made Europe’s heat wave 1 to 4 degrees Celsius (1.8 to 7.2 Fahrenheit) hotter.
The scientists then used research on the relationship between heat and daily deaths to estimate how many people lost their lives.
They found approximately 2,300 people died during ten days of heat across the 12 cities, around 1,500 more than would have died in a world without climate change. In other words, global heating was responsible for 65% of the total death toll.
“The results show how relatively small increases in the hottest temperatures can trigger huge surges in death,” the study authors wrote.
Heat has a particularly pernicious impact on people with underlying health conditions, such as heart disease, diabetes and respiratory problems.
People over 65 years old were most affected, accounting for 88% of the excess deaths, according to the analysis. But heat can be deadly for anyone. Nearly 200 of the estimated deaths across the 12 cities were among those aged 20 to 65.
Climate change was responsible for the vast majority of heat deaths in some cities. In Madrid, it accounted for about 90% of estimated heat wave deaths, the analysis found.
Davidcob
30 Aug 25 at 1:45 pm
купить аттестат за 11 классов дешево [url=https://www.arus-diplom24.ru]купить аттестат за 11 классов дешево[/url] .
Diplomi_pyKn
30 Aug 25 at 1:47 pm
как купить диплом с занесением в реестр в екатеринбурге [url=arus-diplom31.ru]arus-diplom31.ru[/url] .
Vigodno zakazat diplom instityta!_apOl
30 Aug 25 at 1:48 pm
youtube 7288
youtubeiai
30 Aug 25 at 1:49 pm
I blog quite often and I truly appreciate your content.
This great article has truly peaked my interest.
I am going to book mark your site and keep checking for new
information about once per week. I subscribed to your RSS feed as
well.
akhuwat loan online apply
30 Aug 25 at 1:49 pm
где можно купить аттестат за 11 [url=www.educ-ua3.ru/]где можно купить аттестат за 11[/url] .
Diplomi_yuki
30 Aug 25 at 1:50 pm
Its not my first time to visit this web site, i am browsing this site dailly and take nice information from here all the time.
LucroX AI
30 Aug 25 at 1:52 pm
купить диплом с реестром в москве [url=https://www.arus-diplom33.ru]купить диплом с реестром в москве[/url] .
Vigodno priobresti diplom yniversiteta!_baoi
30 Aug 25 at 1:55 pm
высшее образование купить диплом с занесением в реестр [url=www.arus-diplom32.ru]высшее образование купить диплом с занесением в реестр[/url] .
Zakazat diplom o visshem obrazovanii!_dsEn
30 Aug 25 at 1:58 pm
Luxury1288
Luxury1288
30 Aug 25 at 1:58 pm
Описание
Подробнее тут – [url=https://vyvod-iz-zapoya-sochi7.ru/]вывод из запоя цена[/url]
JimmyOmify
30 Aug 25 at 2:02 pm
Планируете ремонт https://remontkomand.kz в Алматы и боитесь скрытых платежей? Опубликовали полный и честный прайс-лист! Узнайте точные расценки на все виды работ — от демонтажа до чистовой отделки. Посчитайте стоимость своего ремонта заранее и убедитесь в нашей прозрачности. Никаких «сюрпризов» в итоговой смете!
remontkomand-945
30 Aug 25 at 2:03 pm
Магазин тут! Отзывы, Качество. kokain gash mefedron alfa-pvp
JamesCic
30 Aug 25 at 2:04 pm
What’s Taking place i’m new to this, I stumbled upon this I’ve found
It absolutely useful and it has aided me out loads.
I am hoping to give a contribution & aid different customers like its helped me.
Good job.
best crypto casinos
30 Aug 25 at 2:07 pm
I’ve learn a few just right stuff here. Definitely price bookmarking for revisiting.
I surprise how much attempt you place to make any such magnificent informative site.
web site
30 Aug 25 at 2:08 pm
It’s in reality a nice and useful piece of
info. I am glad that you simply shared this useful information with us.
Please stay us informed like this. Thank you for sharing.
Quantum Bextra
30 Aug 25 at 2:10 pm
It’s actually a nice and useful piece of info.
I am happy that you simply shared this useful information with us.
Please stay us up to date like this. Thank you for sharing.
LucroX AI
30 Aug 25 at 2:12 pm
The other day, while I was at work, my sister stole
my iphone and tested to see if it can survive a twenty five
foot drop, just so she can be a youtube sensation. My iPad is
now destroyed and she has 83 views. I know this is totally off topic
but I had to share it with someone!
livebet303 slot
30 Aug 25 at 2:13 pm
bonaslot link resmi mudah diakses [url=https://1wbona.com/#]bonaslot jackpot harian jutaan rupiah[/url] bonaslot login
Aaronreima
30 Aug 25 at 2:19 pm
купить диплом образование киеве [url=http://www.educ-ua2.ru]купить диплом образование киеве[/url] .
Diplomi_qqOt
30 Aug 25 at 2:21 pm
Have you ever considered writing an e-book or guest authoring
on other blogs? I have a blog centered on the same subjects
you discuss and would love to have you share
some stories/information. I know my readers would enjoy your
work. If you are even remotely interested, feel free to shoot me an e mail.
Sealife Center
30 Aug 25 at 2:24 pm
Tһе caring atmosphere ɑt OMT motivates curiosity іn mathematics, transforming Singapore trainees іnto
passionate students motivated tߋ accomplish top test outcomes.
Open yߋur child’ѕ comрlete potential іn mathematics ѡith OMT Math Tuition’ѕ expert-led classes, customized t᧐ Singapore’ѕ MOE syllabus for primary,
secondary, and JC trainees.
Singapore’s woгld-renowned math curriculum emphasizes conceptual
understanding οver simple calculation, mɑking
math tuition vital fоr students tⲟ comprehend deep ideas аnd master national examinations ⅼike PSLE
ɑnd O-Levels.
Math tuition addresses specific finding оut rates, permitting primary school trainees t᧐
deepen understanding оf PSLE topics liҝе areɑ, border,
and volume.
Ꮃith О Levels emphasizing geometry proofs aand theorems, math tuition οffers
specialized drills tⲟ mаke sure pupils cаn deal ԝith theѕе ԝith precision and confidence.
Ꮤith A Levels requiring effectiveness іn vectors and
complicated numƄers, math tuition ɡives targeted method t᧐ taҝe care ᧐f
these abstract concepts efficiently.
Ꮃhat collections OMT apаrt is іts custom-made syllabus
tһat lines ᥙp witһ MOE whіle using flexible pacing, allowing advanced pupils tо accelerate tһeir understanding.
Personalized progress monitoring іn OMT’s ѕystem shⲟws
your weak places ѕia, enabling targeted technique fߋr quality improvement.
Ultimately, math tuition іn Singapore transforms potential іnto success, guaranteeing students not simply pass Ьut excel іn their mathematics
tests.
Also visit my website … best math tuition near me
best math tuition near me
30 Aug 25 at 2:25 pm
Магазин тут! Отзывы, Качество. kokain gash mefedron alfa-pvp
JamesCic
30 Aug 25 at 2:26 pm
купить диплом университета с занесением в реестр [url=https://arus-diplom33.ru/]купить диплом университета с занесением в реестр[/url] .
Priobresti diplom yniversiteta!_pcoi
30 Aug 25 at 2:30 pm
диплом купить с занесением в реестр челябинск [url=ashapiter0.forum24.ru/?1-19-0-00001964-000-0-0-1752569817]диплом купить с занесением в реестр челябинск[/url] .
Priobresti diplom ob obrazovanii!_yckt
30 Aug 25 at 2:31 pm
https://onlinegameblog.blogzag.com/80532819/1xbet-promo-code-for-nigeria
LarryOxype
30 Aug 25 at 2:31 pm
Планируете ремонт https://remontkomand.kz в Алматы и боитесь скрытых платежей? Опубликовали полный и честный прайс-лист! Узнайте точные расценки на все виды работ — от демонтажа до чистовой отделки. Посчитайте стоимость своего ремонта заранее и убедитесь в нашей прозрачности. Никаких «сюрпризов» в итоговой смете!
remontkomand-54
30 Aug 25 at 2:32 pm