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!
I really like looking through a post that can make people think.
Also, thank you for allowing for me to comment!
we999 game register
21 Aug 25 at 8:05 pm
https://www.metooo.io/u/689e40ef01467f1582782797
JamesWek
21 Aug 25 at 8:07 pm
Hello there PancakeSwap platform is your DeFi trading hub for liquidity farming CAKE staking and efficient token swaps
PancakeSwapstaking
Robert#Vorkk[Brtgrisvipjesfvn,2,5]
21 Aug 25 at 8:07 pm
Профессиональные детейлинг салона автомобиля: полировка кузова, химчистка салона, восстановление пластика и защита керамикой. Вернём автомобилю блеск и надёжную защиту.
812detailing-120
21 Aug 25 at 8:07 pm
Когда человек оказывается в состоянии алкогольного запоя, самостоятельное преодоление последствий становится практически невозможным. Безопасно выйти из запоя без риска для жизни и здоровья можно только под медицинским наблюдением. В наркологической клинике «Содружество» в Щёлково вывод из запоя проводится круглосуточно, с профессиональной поддержкой, выездом врача на дом и гарантией индивидуального подхода к каждому пациенту. Здесь обеспечивается не только эффективное медикаментозное лечение, но и психологическая поддержка семьи, а также планирование последующего восстановления.
Выяснить больше – [url=https://vyvod-iz-zapoya-shchelkovo6.ru/]вывод из запоя цены щелково[/url]
Williampoord
21 Aug 25 at 8:08 pm
Stavki Prognozy [url=http://www.stavki-prognozy-2.ru]http://www.stavki-prognozy-2.ru[/url] .
stavki prognozy_ikmn
21 Aug 25 at 8:08 pm
Very nice article. I definitely love this website. Thanks!
Eulexin
21 Aug 25 at 8:14 pm
Захватывающий геймплей ждёт вас в 101 Lions.
Alfonzohut
21 Aug 25 at 8:16 pm
Затяжной запой опасен для жизни. Врачи наркологической клиники в Челябинске проводят срочный вывод из запоя — на дому или в стационаре. Анонимно, безопасно, круглосуточно.
Получить больше информации – [url=https://vyvod-iz-zapoya-chelyabinsk11.ru/]vyvod-iz-zapoya-chelyabinsk11.ru[/url]
Williamhib
21 Aug 25 at 8:16 pm
Введение препаратов осуществляется внутривенно, что обеспечивает оперативное действие медикаментов. В состав лечебного раствора входят средства для детоксикации организма, нормализации водно-электролитного и кислотно-щелочного баланса. При необходимости врач дополнительно вводит препараты, защищающие печень, стабилизирующие работу сердца и успокаивающие нервную систему. Вся процедура проводится под строгим контролем нарколога, который следит за состоянием пациента и корректирует терапию при необходимости. По завершении процедуры врач дает пациенту и его родственникам подробные рекомендации по дальнейшему восстановлению и профилактике повторных запоев.
Подробнее можно узнать тут – [url=https://kapelnica-ot-zapoya-nizhniy-novgorod0.ru/]postavit-kapelniczu-ot-zapoya nizhnij novgorod[/url]
Larrybatty
21 Aug 25 at 8:17 pm
купить диплом спб с занесением в реестр [url=https://arus-diplom34.ru/]https://arus-diplom34.ru/[/url] .
Priobresti diplom lubogo yniversiteta!_iqkn
21 Aug 25 at 8:17 pm
Very good information. Lucky me I came across
your site by accident (stumbleupon). I have saved it for
later!
79Club ac
21 Aug 25 at 8:19 pm
купить аттестат за 11 классов в волгограде [url=arus-diplom24.ru]купить аттестат за 11 классов в волгограде[/url] .
Diplomi_qqKn
21 Aug 25 at 8:23 pm
list of compounds chemistry
Normannus
21 Aug 25 at 8:24 pm
https://mez.ink/yw3ttalifey
JamesWek
21 Aug 25 at 8:28 pm
купить аттестат за 11 класс в богданович [url=www.arus-diplom24.ru]купить аттестат за 11 класс в богданович[/url] .
Diplomi_lvKn
21 Aug 25 at 8:28 pm
СтавкиПрогнозы [url=http://stavki-prognozy-2.ru/]http://stavki-prognozy-2.ru/[/url] .
stavki prognozy_ivmn
21 Aug 25 at 8:34 pm
Самостоятельно выйти из запоя — почти невозможно. В Челябинске врачи клиники проводят медикаментозный вывод из запоя с круглосуточным выездом. Доверяйте профессионалам.
Получить больше информации – [url=https://vyvod-iz-zapoya-chelyabinsk12.ru/]вывод из запоя на дому цена челябинск[/url]
WayneBlomy
21 Aug 25 at 8:38 pm
купить медицинский диплом с занесением в реестр [url=http://www.arus-diplom34.ru]купить медицинский диплом с занесением в реестр[/url] .
Zakazat diplom instityta!_sgkn
21 Aug 25 at 8:38 pm
Thanks for the marvelous posting! I certainly enjoyed reading
it, you can be a great author.I will be sure to bookmark your blog and will eventually come back later in life.
I want to encourage one to continue your great writing, have a nice day!
Thuốc lắc
21 Aug 25 at 8:40 pm
IverGrove [url=https://ivergrove.com/#]can i shower after taking ivermectin?[/url] stromectol 3mg cost
MichaelSwace
21 Aug 25 at 8:41 pm
Wonderful blog! Do you have any recommendations for aspiring writers?
I’m planning to start my own website soon but I’m a little lost
on everything. Would you suggest starting with a free platform
like WordPress or go for a paid option? There are so many choices out there that I’m completely overwhelmed ..
Any suggestions? Cheers!
cocaine
21 Aug 25 at 8:43 pm
купить диплом с занесением в реестр в нижнем тагиле [url=https://arus-diplom34.ru]купить диплом с занесением в реестр в нижнем тагиле[/url] .
Priobresti diplom VYZa!_hpkn
21 Aug 25 at 8:45 pm
Hello! This is my first comment here so I just wanted to give a quick shout out and say I genuinely enjoy reading through your
articles. Can you suggest any other blogs/websites/forums that go over the
same subjects? Thanks a ton!
index
21 Aug 25 at 8:48 pm
https://say.la/read-blog/126267
JamesWek
21 Aug 25 at 8:49 pm
https://unitro.ru/
Graigvorgo
21 Aug 25 at 8:50 pm
Основной этап терапии — установка внутривенной капельницы. Через капельницу вводятся специально подобранные растворы, способствующие быстрому выведению токсинов, восстановлению водно-электролитного баланса и нормализации работы внутренних органов. При необходимости врач назначает дополнительные медикаменты для защиты печени, стабилизации сердечной деятельности и купирования симптомов абстинентного синдрома. В течение всей процедуры состояние пациента контролируется врачом, который корректирует схему лечения для достижения наилучших результатов. По завершении процедуры специалист дает подробные рекомендации по дальнейшему восстановлению и профилактике повторных запоев.
Детальнее – [url=https://kapelnica-ot-zapoya-nizhniy-novgorod00.ru/]капельница от запоя на дому в нижний новгороде[/url]
Jamesvob
21 Aug 25 at 8:53 pm
Каждая процедура проводится под контролем квалифицированного врача. При необходимости возможен экстренный выезд специалиста на дом, что позволяет оказать помощь пациенту в привычной и безопасной обстановке.
Изучить вопрос глубже – https://vyvod-iz-zapoya-odincovo6.ru/vyvod-iz-zapoya-na-domu-v-odincovo
Gregoryflony
21 Aug 25 at 8:56 pm
always i used to read smaller content which as well clear their
motive, and that is also happening with this paragraph which I am reading now.
Look at my web-site :: 안전놀이터
안전놀이터
21 Aug 25 at 9:00 pm
где купить аттестаты за 11 [url=www.arus-diplom24.ru]www.arus-diplom24.ru[/url] .
Diplomi_tvKn
21 Aug 25 at 9:02 pm
Great blog here! Also your web site loads up fast!
What web host are you using? Can I get your affiliate link to
your host? I wish my site loaded up as quickly as yours lol
RovonixFlex 2.1 Ai
21 Aug 25 at 9:04 pm
It is appropriate time to make some plans for the future and it’s time to be happy.
I have read this post and if I could I desire to suggest you few interesting things
or suggestions. Maybe you can write next articles referring to this article.
I wish to read even more things about it!
حقوق معلمی یا پرستاری نی نی سایت
21 Aug 25 at 9:04 pm
Undeniably believe that which you said. Your favorite reason seemed to be on the
net the easiest thing to be aware of. I say to
you, I definitely get irked while people think about worries that they just don’t know
about. You managed to hit the nail upon the top and
also defined out the whole thing without having side-effects
, people could take a signal. Will likely be back to get more.
Thanks
penipu
21 Aug 25 at 9:06 pm
It’s amazing in favor of me to have a site,
which is valuable in favor of my know-how.
thanks admin
استخدام سراسری معلمان در مجموعه دبیریاب
21 Aug 25 at 9:07 pm
ставки прогнозы [url=www.stavki-prognozy-2.ru/]www.stavki-prognozy-2.ru/[/url] .
stavki prognozy_kcmn
21 Aug 25 at 9:07 pm
Good post! We are linking to this particularly great content on our site.
Keep up the great writing.
ciclismoenred.com
21 Aug 25 at 9:08 pm
I have to thank you for the efforts you’ve put in penning this
website. I am hoping to view the same high-grade blog posts by you in the future as well.
In truth, your creative writing abilities has inspired
me to get my own, personal blog now 😉
dora88
21 Aug 25 at 9:09 pm
https://wanderlog.com/view/jdbxreebia/купить-экстази-кокаин-амфетамин-ванадзор/shared
JamesWek
21 Aug 25 at 9:10 pm
Hi there, You have done an incredible job. I will certainly digg it
and personally suggest to my friends. I am sure they will be benefited from this web
site.
Ridgewell Tradebit
21 Aug 25 at 9:13 pm
If some one wants to be updated with most up-to-date technologies therefore he must be pay a quick visit this website and be up to
date every day.
Frame Flarex Nx
21 Aug 25 at 9:13 pm
ProstaVive is a natural supplement designed to support prostate health, urinary comfort, and overall
male wellness. Its formula targets inflammation and hormonal balance,
helping reduce frequent bathroom trips and improving
daily confidence. Many men appreciate it as a safe, effective
way to maintain long-term prostate health without harsh side effects.
ProstaVive
21 Aug 25 at 9:13 pm
купить диплом в москве с занесением в реестр [url=http://www.arus-diplom31.ru]купить диплом в москве с занесением в реестр[/url] .
Diplomi_uapl
21 Aug 25 at 9:15 pm
ivermectin 3mg tablets price: IverGrove – why is stromectol prescribed
WayneViemo
21 Aug 25 at 9:17 pm
LeptoFix is a popular supplement that targets leptin resistance, which can be a hidden factor behind stubborn weight gain. By supporting
healthy metabolism and appetite control, it helps the body burn fat more effectively while boosting energy
levels. Many people like it because it offers a
natural and supportive way to reach weight loss goals without relying on extreme diets
or harsh stimulants.
LeptoFix
21 Aug 25 at 9:20 pm
Joint N-11 is a natural supplement formulated to
improve joint flexibility, reduce stiffness, and support overall
mobility. Its blend of carefully chosen ingredients works to
ease discomfort and promote long-term joint health.
Many users appreciate it as a safe and effective way to
stay active, comfortable, and independent as they age.
Joint N-11
21 Aug 25 at 9:23 pm
купить проведенный аттестат за 11 класс [url=http://www.arus-diplom24.ru]купить проведенный аттестат за 11 класс[/url] .
Diplomi_aoKn
21 Aug 25 at 9:24 pm
Hello there, I discovered your web site via Google even as looking for a comparable topic, your web site
came up, it seems great. I’ve bookmarked it in my google bookmarks.
Hi there, simply turned into alert to your blog thru Google,
and found that it’s really informative. I’m going to watch out for brussels.
I’ll be grateful should you proceed this in future.
Lots of other people can be benefited out of your writing.
Cheers!
해외 룸 알바
21 Aug 25 at 9:27 pm
FertiCare Online [url=http://ferticareonline.com/#]buy generic clomid pill[/url] can i get generic clomid
MichaelSwace
21 Aug 25 at 9:29 pm
https://kemono.im/odegifybwec/grats-kupit-gashish-boshki-marikhuanu
JamesWek
21 Aug 25 at 9:31 pm
купить диплом о высшем образовании легально [url=http://arus-diplom31.ru]купить диплом о высшем образовании легально[/url] .
Diplomi_rbpl
21 Aug 25 at 9:33 pm