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!
номер аккаунта телеграмм
NormanJaf
21 Oct 25 at 6:22 pm
протокол испытания
JosephDum
21 Oct 25 at 6:23 pm
виртуальный номер телеграмм
NormanJaf
21 Oct 25 at 6:23 pm
Как купить Метамфетамин в Юрьевеце?Смотрите, что нашел – https://na-ohte.ru
. Цены порадовали, доставка заявлена. Может, кто-то тестил у них? Как у них с надежностью?
Stevenref
21 Oct 25 at 6:24 pm
протокол испытания
JosephDum
21 Oct 25 at 6:24 pm
seo ranking services [url=https://www.reiting-seo-kompanii.ru]seo ranking services[/url] .
reiting seo kompanii_afsn
21 Oct 25 at 6:24 pm
заказать сео москва [url=http://www.reiting-seo-agentstv-moskvy.ru]http://www.reiting-seo-agentstv-moskvy.ru[/url] .
reiting seo agentstv moskvi_lhMl
21 Oct 25 at 6:25 pm
агентство поискового продвижения [url=http://reiting-seo-agentstv-moskvy.ru]агентство поискового продвижения[/url] .
reiting seo agentstv moskvi_omMl
21 Oct 25 at 6:28 pm
https://boi.instgame.pro/forum/index.php?topic=137253.0
RobertHop
21 Oct 25 at 6:29 pm
рейтинг сео [url=http://www.seo-prodvizhenie-reiting.ru]http://www.seo-prodvizhenie-reiting.ru[/url] .
seo prodvijenie reiting_akEa
21 Oct 25 at 6:32 pm
рейтинг агентств digital россии [url=https://luchshie-digital-agencstva.ru/]https://luchshie-digital-agencstva.ru/[/url] .
lychshie digital agentstva_qmoi
21 Oct 25 at 6:32 pm
Если вы ищете надежную клинику для вывода из запоя, обратитесь в «Детокс» в Краснодаре. Услуга вызова нарколога на дом доступна круглосуточно. Врачи приедут к вам в течение 1–2 часов и окажут необходимую помощь.
Детальнее – [url=https://narkolog-na-dom-krasnodar25.ru/]нарколог капельница на дом краснодар[/url]
Isidromib
21 Oct 25 at 6:32 pm
seo expert ranking [url=http://top-10-seo-prodvizhenie.ru/]http://top-10-seo-prodvizhenie.ru/[/url] .
top 10 seo prodvijenie_ihKa
21 Oct 25 at 6:33 pm
продвижение сайта +в топ [url=http://reiting-runeta-seo.ru]http://reiting-runeta-seo.ru[/url] .
reiting ryneta seo_mxma
21 Oct 25 at 6:33 pm
Привет всем!
купить виртуальный номер для смс навсегда — это надёжность и стабильность на долгие годы. Каждому нужен купить виртуальный номер для смс навсегда для безопасности личных данных. Выбирайте наш сервис, чтобы купить виртуальный номер для смс навсегда с удобством. Наши клиенты рекомендуют купить виртуальный номер для смс навсегда друзьям и коллегам. купить виртуальный номер для смс навсегда — это цифровая свобода и приватность.
Полная информация по ссылке – https://gomelstreet.by/ispolzovanie-virtualnyh-nomerov-dlya-rosta-biznesa-preimushhestva-i-strategicheskie-idei.html
купить виртуальный номер навсегда, постоянный виртуальный номер, купить виртуальный номер навсегда
Виртуальный номер, купить виртуальный номер навсегда, купить виртуальный номер
Удачи и комфорта в общении!
Lynwoodassok
21 Oct 25 at 6:34 pm
https://bioniclerpg.getbb.ru/viewtopic.php?f=6&t=9042
Randygaisa
21 Oct 25 at 6:34 pm
рейтинг агентств digital услуг [url=www.luchshie-digital-agencstva.ru/]www.luchshie-digital-agencstva.ru/[/url] .
lychshie digital agentstva_xxoi
21 Oct 25 at 6:35 pm
https://bioniclerpg.getbb.ru/viewtopic.php?f=6&t=9042
Randygaisa
21 Oct 25 at 6:35 pm
seo top agencies [url=https://www.reiting-seo-kompanii.ru]https://www.reiting-seo-kompanii.ru[/url] .
reiting seo kompanii_fgsn
21 Oct 25 at 6:37 pm
компании по продвижению сайтов в москве [url=seo-prodvizhenie-reiting-kompanij.ru]seo-prodvizhenie-reiting-kompanij.ru[/url] .
seo prodvijenie reiting kompanii_qast
21 Oct 25 at 6:38 pm
продвижение сайтов в топ 10 москва [url=www.reiting-kompanii-po-prodvizheniyu-sajtov.ru]продвижение сайтов в топ 10 москва[/url] .
agentstvo poiskovogo prodvijeniya_naKt
21 Oct 25 at 6:39 pm
seo продвижение сайта компании москва [url=www.reiting-seo-agentstv-moskvy.ru/]www.reiting-seo-agentstv-moskvy.ru/[/url] .
reiting seo agentstv moskvi_tiMl
21 Oct 25 at 6:39 pm
U888 được xem là một nền tảng cá cược mới mẻ
nhưng nhanh chóng gây ấn tượng mạnh mẽ trong giới bet thủ.
Không chỉ khẳng định chỗ đứng vững chắc
tại Việt Nam, đơn vị này còn vươn lên trở thành một trong những nhà cái đẳng cấp hàng đầu khu
vực Châu Á. Hãy cùng khám phá nguyên nhân khiến U888 luôn là lựa chọn hàng đầu qua bài viết dưới đây.
https://kewlllc.us.com/
u888
21 Oct 25 at 6:39 pm
Parents, composed lah, enrolling іn a well-known primary school еnsures smaⅼler class sizes f᧐r personalized
focus аnd tߋp PSLE marks.
Hey hey, steady lah, renowned schools possess gardening initiatives, educating eco-friendliness fⲟr environmental positions.
Beѕides frօm establishment resources, concentrate оn mathematics tߋ prevent common mistakes ѕuch
aѕ inattentive errors іn assessments.
Ⲟh dear, wіthout solid math ɗuring primary school, еven prestigious
school kids mɑy stumble at secondary equations, tһerefore build tһat noѡ leh.
Folks, worry ɑbout thе gap hor, arithmetic groundwork
proves vital ⅾuring primary school tо understanjding figures, crucial іn today’s
tech-driven market.
Parents, fear tһe disparity hor, math foundation proves
vital іn primary school fօr grasping data, esssential іn modern digital system.
In ɑddition frօm establishment amenities, emphasize ᴡith math to prevent common mistakes ѕuch as inattentive blunders at assessments.
Juying Primary School сreates a dynamic setting tһat motivates knowing аnd advancement.
Ꮃith enthusiastic instructors, іt influences trainee success.
Nan Chiau Primary School supplies bilingual knowing ԝith cultural
focus.
Ƭһe school constructs strong scholastic ɑnd social
skills.
It’ѕ perfect fоr heritage preservation.
My web blog: Yio Chu Kang Secondary School [Fred]
Fred
21 Oct 25 at 6:40 pm
https://guryevsk.forum24.ru/?1-3-0-00000637-000-0-0-1758300727
RobertHop
21 Oct 25 at 6:42 pm
Alas, no matter withіn prestigious institutions,children demand extra
maths emphasis fօr thrive at strategies, tһat opens opportunities
into talented programs.
River Valley Ηigh School Junior College integrates bilingualism аnd ecological stewardship, developing eco-conscious
leaders ԝith international ρoint of views. Modern labs аnd green efforts
support innovative knowing іn sciences and humanities.Trainees engage іn cultural immersions аnd service jobs,
improving compassion аnd skills. The school’ѕ unified community
promotes durability аnd teamwork throᥙgh sports and arts.
Graduates ɑre prepared for success іn universities ɑnd beyond, embodying fortitude and cultural acumen.
Eunoia Junior College embodies tһe pinnacle of modern
academic development, housed іn a striking higһ-rise campus tһat
seamlessly incorporates communal knowing spaces,
green аreas, and advanced technological centers t᧐ create an motivating environment
fօr collective ɑnd experiential education. Тhe college’ѕ unique viewpoint of ” stunning thinking” encourages students tо blend intellectual
curiosity ԝith compassion and ethical thinking, supported ƅү
vibrant academic programs іn tһе arts, sciences, аnd interdisciplinary studies tһat promote creative analytical аnd forward-thinking.
Equipped witһ t᧐ρ-tier centers ѕuch aѕ professional-grade performing arts theaters, multimedia studios,
ɑnd interactive science laboratories, trainees ɑre ekpowered to pursue
tһeir enthusiasms and develop exceptional skills іn a holistic wаy.Thrߋugh strategic
partnerships ѡith leading universities аnd industry
leaders, tһe college provideѕ enriching chances for undergraduate-level
гesearch study, internships, ɑnd mentorship tһat bridge
classroom knowing with real-woгld applications.
Аs a outcome, Eunoia Junior College’ѕ students
progress іnto thoughtful, resilient leaders ᴡho are not just
academically accomplished һowever аlso deeply committed tо
contributing favorably tօ a varied and еver-evolving
global society.
Αvoid take lightly lah, link a good Junior College alongside maths excellence fοr assure elevated Ꭺ Levels гesults ɑnd effortless shifts.
Folks, fear tһe disparity hor, mathematics foundation proves essential
іn Junior College to understanding data, vital іn today’s tech-driven economy.
Parents, competitive mode engaged lah, strong primary mathematics guides іn superior scientific grasp ρlus engineering aspirations.
Ɗon’t play play lah, pair а excellent Junior College ρlus mathematics proficiency t᧐ assure elevated A Levels marks ɑs well
as smooth shifts.
Mums ɑnd Dads, fear tһe disparity hor, maths base remains vital during Junior College t᧐ understanding figures, crucial ᴡithin tߋday’ѕ online market.
Be kiasu and start еarly; procrastinating in JC leads tօ mediocre A-level reѕults.
Dⲟ not play play lah, pair а good Junior College pⅼus
mathematics superiority іn orⅾer to ensure elevated
A Levels scores ⲣlus smooth transitions.
mypage; Kaizenaire math tuition singapore
Kaizenaire math tuition singapore
21 Oct 25 at 6:43 pm
https://boi.instgame.pro/forum/index.php?topic=137254.0
Randygaisa
21 Oct 25 at 6:43 pm
top digital agency [url=http://www.luchshie-digital-agencstva.ru]top digital agency[/url] .
lychshie digital agentstva_ycoi
21 Oct 25 at 6:44 pm
seo продвижение цена в месяц [url=https://reiting-runeta-seo.ru/]seo продвижение цена в месяц[/url] .
reiting ryneta seo_tuma
21 Oct 25 at 6:45 pm
seo агенция [url=https://www.reiting-seo-agentstv.ru]https://www.reiting-seo-agentstv.ru[/url] .
reiting seo agentstv_qesa
21 Oct 25 at 6:45 pm
I enjoy what you guys are up too. Such clever work and
exposure! Keep up the excellent works guys I’ve added you guys
to my personal blogroll.
Ropnetrixel
21 Oct 25 at 6:47 pm
топ 10 сео компаний [url=https://seo-prodvizhenie-reiting.ru]https://seo-prodvizhenie-reiting.ru[/url] .
seo prodvijenie reiting_piEa
21 Oct 25 at 6:49 pm
топ seo компаний [url=reiting-seo-kompanii.ru]топ seo компаний[/url] .
reiting seo kompanii_czsn
21 Oct 25 at 6:49 pm
сео продвижение сайтов топ москва [url=http://reiting-kompanii-po-prodvizheniyu-sajtov.ru]сео продвижение сайтов топ москва[/url] .
agentstvo poiskovogo prodvijeniya_ofKt
21 Oct 25 at 6:50 pm
рейтинг агентств digital услуг [url=https://luchshie-digital-agencstva.ru/]https://luchshie-digital-agencstva.ru/[/url] .
lychshie digital agentstva_mpoi
21 Oct 25 at 6:51 pm
лучшее сео продвижение [url=https://reiting-seo-agentstv.ru/]https://reiting-seo-agentstv.ru/[/url] .
reiting seo agentstv_mssa
21 Oct 25 at 6:51 pm
https://bestforum.forum-top.ru/viewtopic.php?id=3846#p6634
RobertHop
21 Oct 25 at 6:51 pm
What’s up to all, the contents existing at this site are really amazing
for people knowledge, well, keep up the good work fellows.
https://angarabayu2323.wixsite.com/
21 Oct 25 at 6:54 pm
https://www.floristic.ru/forum/groups/moskva-d1340-dostavka-cvetov-v-moskve.html#gmessage1892
Randygaisa
21 Oct 25 at 6:54 pm
топ seo специалистов [url=http://top-10-seo-prodvizhenie.ru/]http://top-10-seo-prodvizhenie.ru/[/url] .
top 10 seo prodvijenie_gvKa
21 Oct 25 at 6:55 pm
Отделанные сложные комплексы автоматизации бизнеса:
путь к производительности да росту
ссылка
21 Oct 25 at 6:56 pm
лучшее сео продвижение [url=https://seo-prodvizhenie-reiting.ru/]https://seo-prodvizhenie-reiting.ru/[/url] .
seo prodvijenie reiting_ziEa
21 Oct 25 at 6:57 pm
всем привет.супер магаз))) позже отзыв отпишу. ))))
https://volnovakhaem.ru
заметил, что там тс появляется на много чаще
ErwinAroug
21 Oct 25 at 6:59 pm
search optimisation agency [url=www.reiting-runeta-seo.ru/]www.reiting-runeta-seo.ru/[/url] .
reiting ryneta seo_gxma
21 Oct 25 at 7:03 pm
seo продвижение россия [url=https://www.reiting-kompanii-po-prodvizheniyu-sajtov.ru]seo продвижение россия[/url] .
agentstvo poiskovogo prodvijeniya_trKt
21 Oct 25 at 7:03 pm
рейтинг seo [url=https://www.seo-prodvizhenie-reiting.ru]https://www.seo-prodvizhenie-reiting.ru[/url] .
seo prodvijenie reiting_ylEa
21 Oct 25 at 7:03 pm
Code promo sur 1xBet est unique et permet a chaque nouveau joueur de beneficier jusqu’a 100€ de bonus sportif a hauteur de 100% en 2026. Le bonus sera ajoute a votre solde en fonction de votre premier depot, le depot minimum etant fixe a 1€. Pour eviter toute perte de bonus, veillez a copier soigneusement le code depuis la source et a le saisir dans le champ « code promo (si disponible) » lors de l’inscription, afin de preserver l’integrite de la combinaison. Le bonus de bienvenue n’est pas la seule promotion ou vous pouvez utiliser un code, d’autres combinaisons vous permettant d’obtenir des bonus supplementaires sont disponibles dans la section « Vitrine des codes promo ». Consultez le lien pour plus d’informations sur les promotions disponibles — Code Promo 1xbet Congo. Grace au code promo 1xBet gratuit, obtenez un pari gratuit 1xBet ou un bonus sans depot 1xBet. Le code promotionnel 1xBet valide vous permet de beneficier d’un bonus de bienvenue 1xBet 2026 sur vos premiers paris. Essayez le code promo sport 1xBet pour miser sans risque et decouvrir la plateforme.
Marvinspaft
21 Oct 25 at 7:03 pm
https://priroda77.forum24.ru/?1-3-0-00002743-000-0-0-1758300687
RobertHop
21 Oct 25 at 7:04 pm
https://britmedsuk.com/# BritMedsUk
MichaelZow
21 Oct 25 at 7:04 pm
Если вы ищете надежную клинику для вывода из запоя, обратитесь в «Детокс» в Краснодаре. Услуга вызова нарколога на дом доступна круглосуточно. Врачи приедут к вам в течение 1–2 часов и окажут необходимую помощь.
Разобраться лучше – [url=https://narkolog-na-dom-krasnodar25.ru/]вызвать нарколога на дом срочно[/url]
Isidromib
21 Oct 25 at 7:05 pm