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-diplom4.ru]купить диплом о высшем образовании легально[/url] .
Diplomi_jgOl
25 Oct 25 at 6:18 pm
купить диплом с занесением в реестр оренбург [url=www.frei-diplom2.ru]купить диплом с занесением в реестр оренбург[/url] .
Diplomi_saEa
25 Oct 25 at 6:20 pm
1xbet giri?i [url=1xbet-15.com]1xbet giri?i[/url] .
1xbet_ripl
25 Oct 25 at 6:21 pm
https://www.blogger.com/profile/04405899256651676218
Charleswrinc
25 Oct 25 at 6:22 pm
купить диплом в дзержинске [url=http://rudik-diplom8.ru]купить диплом в дзержинске[/url] .
Diplomi_miMt
25 Oct 25 at 6:22 pm
Heren Gezondheid: Viagra online kopen Nederland – Sildenafil zonder recept bestellen
RandySkync
25 Oct 25 at 6:23 pm
В поисках стабильного поставщика редкоземельных металлов и сплавов? Ознакомьтесь с предложением компании Редметсплав.рф. Мы предоставляем широкий выбор продукции, обеспечивая безупречное качество каждого изделия.
Редметсплав.рф защищает все этапы сделки, предоставляя полный набор документов для регистрации товаров. Независимо от того, нужны ли вам небольшие партии или крупные оптовые поставки, мы готовы удовлетворить любой заказ с высшим уровнем сервиса.
Наша команда консультантов всегда готова помочь в выборе подходящих изделий и ответить на вопросы, связанные с характеристиками и применением металлов. Выбирая нас, вы выбираете уверенность в каждом аспекте сотрудничества.
Посетите наш сайт Редметсплав.рф и убедитесь, что наши стандарты качества и сервиса — это оптимальное решение для вашего бизнеса.
Наш ассортимент:
Магниевый пруток 36 мм МА15 ГОСТ 18351-73 Приобретите магниевый пруток высокого качества для различных отраслей промышленности. Идеальное сочетание прочности, легкости и коррозионной стойкости делает этот материал незаменимым в авиационной, автомобильной и медицинской отраслях. Обеспечьте надежность и долговечность вашей продукции, выбирая магниевый пруток.
SheilaAlemn
25 Oct 25 at 6:24 pm
скачать мостбет [url=http://mostbet12032.ru]скачать мостбет[/url]
mostbet_kg_xrmt
25 Oct 25 at 6:25 pm
Hi there to every , as I am genuinely keen of reading this
webpage’s post to be updated daily. It contains
fastidious data.
stahlwandpool bestellen
25 Oct 25 at 6:25 pm
мостбет официальный сайт регистрация [url=https://www.mostbet12032.ru]https://www.mostbet12032.ru[/url]
mostbet_kg_lkmt
25 Oct 25 at 6:26 pm
I’ve been exploring for a little bit for any high-quality articles
or blog posts on this sort of area . Exploring in Yahoo I at last stumbled upon this web site.
Studying this info So i’m happy to convey that I have a very excellent uncanny feeling I discovered exactly what I needed.
I such a lot definitely will make sure to don?t put out of your mind this web site and provides it a glance regularly.
kra28 cc
25 Oct 25 at 6:27 pm
Excellent way of explaining, and nice paragraph to obtain data on the
topic of my presentation topic, which i am going to present in university.
bokep viral
25 Oct 25 at 6:27 pm
https://finders.golocaly.online/1xbet-bonus-promo-code-bangladesh-2026-up-to-%e0%a7%b313000/
wthpmcy
25 Oct 25 at 6:27 pm
xbet giri? [url=www.1xbet-16.com/]xbet giri?[/url] .
1xbet_cyOn
25 Oct 25 at 6:28 pm
кракен Россия
kraken tor
JamesDaync
25 Oct 25 at 6:29 pm
Кто делал уничтожение клопов цена холодным туманом? Эффективно ли?
дезинфекция после животного
KennethceM
25 Oct 25 at 6:31 pm
That is very attention-grabbing, You’re an excessively
professional blogger. I have joined your feed and look forward to in search of more of your wonderful post.
Additionally, I have shared your website in my social networks
homepage
25 Oct 25 at 6:32 pm
shopwithconfidence – This website really makes online purchases feel fast and safe.
Roberto Phomsoukha
25 Oct 25 at 6:34 pm
После дезинфекция запах исчез, дом свежий!
обработка от клопов частного дома
KennethceM
25 Oct 25 at 6:36 pm
купить диплом с проводкой одно [url=http://www.frei-diplom2.ru]купить диплом с проводкой одно[/url] .
Diplomi_ndEa
25 Oct 25 at 6:36 pm
купить диплом в саратове [url=rudik-diplom10.ru]купить диплом в саратове[/url] .
Diplomi_qcSa
25 Oct 25 at 6:36 pm
Sildenafil-tabletter pris: erektionspiller på nätet – Sildenafil-tabletter pris
Jesuskax
25 Oct 25 at 6:37 pm
купить диплом техникума в курске [url=frei-diplom8.ru]купить диплом техникума в курске[/url] .
Diplomi_musr
25 Oct 25 at 6:39 pm
1xbetgiri? [url=http://www.1xbet-12.com]http://www.1xbet-12.com[/url] .
1xbet_xwSr
25 Oct 25 at 6:39 pm
купить диплом электромонтажника [url=http://rudik-diplom5.ru/]купить диплом электромонтажника[/url] .
Diplomi_suma
25 Oct 25 at 6:40 pm
I’m really impressed along with your writing talents as neatly as with the structure to your
weblog. Is that this a paid topic or did you modify it your self?
Either way stay up the excellent quality writing, it is rare to look a nice blog
like this one today..
Avenir Bitrevo
25 Oct 25 at 6:40 pm
сколько стоит купить диплом медсестры [url=https://frei-diplom15.ru/]сколько стоит купить диплом медсестры[/url] .
Diplomi_eroi
25 Oct 25 at 6:40 pm
купить диплом с занесением в реестр самара [url=www.frei-diplom5.ru/]www.frei-diplom5.ru/[/url] .
Diplomi_ytPa
25 Oct 25 at 6:41 pm
Playamo digital casino brings an exceptional gaming journey with in excess of 3,000+ premium slot titles, table options, and live gaming experiences from award-winning software creators. From modern video slots to tactical blackjack matches and genuine live casino, the platform meets diverse needs. The platform offers an modern, intuitive system that delivers fluid browsing on all devices, letting you play enjoyment whenever and wherever.
Playamo casino
AlfredLog
25 Oct 25 at 6:41 pm
Pretty great post. I just stumbled upon your blog and wanted to say that I’ve truly
loved browsing your blog posts. In any case I’ll be subscribing on your feed
and I hope you write once more very soon!
balondor88
25 Oct 25 at 6:41 pm
Hi to all, it’s truly a good for me to go to see this web
page, it includes priceless Information.
web site
25 Oct 25 at 6:42 pm
купить диплом в архангельске с занесением в реестр [url=frei-diplom2.ru]купить диплом в архангельске с занесением в реестр[/url] .
Diplomi_fvEa
25 Oct 25 at 6:42 pm
купить диплом в магадане [url=https://rudik-diplom3.ru/]купить диплом в магадане[/url] .
Diplomi_eyei
25 Oct 25 at 6:43 pm
диплом настоящий купить с занесением в реестр [url=https://www.frei-diplom2.ru]https://www.frei-diplom2.ru[/url] .
Diplomi_njEa
25 Oct 25 at 6:46 pm
https://herengezondheid.shop/# goedkope Viagra tabletten online
Hermanereli
25 Oct 25 at 6:46 pm
hoki1881
hoki1881
25 Oct 25 at 6:48 pm
https://ragingbookmarks.com/story20476191/1xbet-registration-promo-code
rsnqlel
25 Oct 25 at 6:49 pm
what is nasal wash
PHP hook, building hooks in your application – Sjoerd Maessen blog at Sjoerd Maessen blog
what is nasal wash
25 Oct 25 at 6:49 pm
1 xbet [url=https://www.1xbet-15.com]1 xbet[/url] .
1xbet_uspl
25 Oct 25 at 6:50 pm
1xbet guncel [url=http://1xbet-16.com]1xbet guncel[/url] .
1xbet_fgOn
25 Oct 25 at 6:50 pm
купить диплом техникума в иркутске lr 63 [url=http://frei-diplom8.ru]купить диплом техникума в иркутске lr 63[/url] .
Diplomi_jusr
25 Oct 25 at 6:51 pm
newseasoncollection – Easy to navigate, found exactly what I was looking for.
Roberto Uziel
25 Oct 25 at 6:51 pm
скачать mostbet на телефон [url=https://www.mostbet12031.ru]скачать mostbet на телефон[/url]
mostbet_kg_owMa
25 Oct 25 at 6:53 pm
кракен 2025
кракен android
JamesDaync
25 Oct 25 at 6:54 pm
Thanks for sharing your thoughts about ankara kürtaj. Regards
ankara kürtaj
25 Oct 25 at 6:57 pm
Кто делал уничтожение клопов цена холодным туманом? Эффективно ли?
уничтожение клопов горячим туманом
KennethceM
25 Oct 25 at 6:59 pm
Secondary school math tuition iѕ key in Singapore’ѕ education framework,
offering personalized guidance fоr your child fresh fгom PSLE tto excel іn neᴡ
topics liқe equations.
Don’t anyhoѡ lor, Singapore’s t᧐p math ranking іs fact sіa!
Parents, deal ԝith aspirations wіth Singaporre math
tuition’ѕ sped up choices. Secondary math tuition supports gifted minds.
Ԝith secondary 1 math tuition, reasoning іs strengthened from day one.
Oսtside obstacles іn secondary 2 math tuition fіx genuine puzzles.
Secondary 2 math tuition applies theory outdoors.
Experiential secondary 2 math tuition strengthens ideas.
Secondary 2 math tuition experiences await.
Secondary 3 math exams hold weight, оne yеar frоm O-Levels,
underscoring excellence. Standing ⲟut facilitates truthful ԝork.
Success promotes budget friendly options.
Ƭhe pivotal secondary 4 exams explore heritage іn Singapore.
Secondary 4 math tuition translates art ⲣoint of views.
Тhis culture enhances Ⲟ-Level understanding.
Secondary 4 math tuition appreciates рast.
Math ցoes furtһer thɑn exam scores; it’s ɑ vital talent
іn surging AI technologies, essential f᧐r traffic flow optimization.
Nurture an enduring love for mathematics аnd embed itѕ principles into yoᥙr daily real-life
decisions f᧐r superior performance.
Α core benefit is that ρast math papers fгom varіous schools іn Singapore provide insights іnto evolving exam trends for secondary level.
Leveraging online math tuitiuon е-learning helps Singapore students ᴡith satellite data analysis
fоr real math apps.
Wah ѕia, don’t fret ah, secondary school fun ᧐ne, no need to pressure yoսr kid unduly.
Adaptable pacing іn OMT’s е-learning аllows trainees savor math triumphes, constructing deep love аnd ideas for exanination performance.
Join оur ѕmall-ցroup on-site classes in Singapore for personalized
assistance іn a nurturing environment that develops strong foundational mathematics
abilities.
Ӏn a system ѡhere math education һаs progressed to foter
development ɑnd worldwide competitiveness, enrolling іn math tuition makеs suгe students
stay ahead by deepening their understanding and application of essential concepts.
primary school math tuition іs crucial for PSLE preparation ɑs
іt assists students master tһе foundational principles
like portions ɑnd decimals, wһіch аre heavily evaluated
іn the exam.
Tuition cultivates innovative analytic abilities, critical f᧐r resolving
tһe complex, multi-step concerns tһɑt define O Level mathematics obstacles.
Junior college tuition ߋffers access to auxiliary resources
ⅼike worksheets ɑnd video explanations, reinforcing A Level syllabus protection.
Unique fгom otherѕ, OMT’s syllabus matches MOE’ѕ with
a concentrate ߋn resilience-building workouts, aiding pupils tɑke ⲟn difficult issues.
Unrestricted retries ⲟn tests sia, ideal f᧐r grasping topics аnd attaining th᧐se Ꭺ grades in mathematics.
Singapore’ѕ focus on analytical in mathematics examinations mаkes tuition neϲessary for developing imрortant thinking skills рast school hoᥙrs.
Here is my web page … sec math tuition
sec math tuition
25 Oct 25 at 6:59 pm
диплом техникума с отличием купить [url=http://educ-ua7.ru/]http://educ-ua7.ru/[/url] .
Diplomi_vtea
25 Oct 25 at 7:00 pm
sportwetten bonus ohne einzahlung neu
Review my website: Wettanbieter im Vergleich
Wettanbieter im Vergleich
25 Oct 25 at 7:00 pm
купить свидетельство о рождении [url=http://www.rudik-diplom4.ru]купить свидетельство о рождении[/url] .
Diplomi_iyOr
25 Oct 25 at 7:00 pm