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!
Hello I am so thrilled I found your website, I really found you by error, while I was browsing on Aol for something else, Regardless I am
here now and would just like to say thanks for a remarkable post and a
all round interesting blog (I also love the theme/design),
I don’t have time to read through it all at the moment but I
have book-marked it and also included your RSS feeds, so when I have time I will be back to read a lot
more, Please do keep up the great work.
BlorBytAi
5 Oct 25 at 3:00 pm
fruit and tree nuts industry consists of a wide array of crops and products generating,on average,高級 ラブドール
ラブドール
5 Oct 25 at 3:01 pm
классический массаж МАССАЖ В ЧЕЛЯБИНСКЕ НЕДОРОГО – это реально! В Челябинске можно найти массажные салоны и центры, предлагающие доступные цены на массажные услуги. Не отказывайте себе в удовольствии и пользе массажа из-за высокой стоимости. Найдите подходящий вариант и насладитесь приятной и полезной процедурой по доступной цене!
Williamhep
5 Oct 25 at 3:02 pm
I am sure this piece of writing has touched all the internet people, its really really pleasant post on building up new weblog.
turkey visa from australia
5 Oct 25 at 3:03 pm
Wow! After all I got a webpage from where I can really
take useful facts regarding my study and knowledge.
79 king
5 Oct 25 at 3:04 pm
медицинское оборудование россия [url=http://xn—–6kcdfldbfd2aga1bqjlbbb4b4d7d1fzd.xn--p1ai]http://xn—–6kcdfldbfd2aga1bqjlbbb4b4d7d1fzd.xn--p1ai[/url] .
oborydovanie medicinskoe_bgOn
5 Oct 25 at 3:06 pm
ставки на хоккей сегодня прогнозы [url=www.prognozy-na-khokkej5.ru]www.prognozy-na-khokkej5.ru[/url] .
prognozi na hokkei_wdEa
5 Oct 25 at 3:08 pm
оборудование медицинское [url=www.xn—-7sbcejdfbbzea0axlidbbn0a0b5a8f.xn--p1ai]оборудование медицинское[/url] .
oborydovanie medicinskoe_zbsi
5 Oct 25 at 3:08 pm
Мы работаем с триггерами, режимом сна/питания, энергобалансом и типичными стрессовыми ситуациями. Короткие и регулярные контрольные контакты снижают риск рецидива и помогают уверенно вернуться к работе и бытовым задачам.
Получить дополнительную информацию – [url=https://narkologicheskaya-klinika-mytishchi0.ru/]наркологическая клиника обратный звонок[/url]
PhillipSok
5 Oct 25 at 3:10 pm
http://clomicareusa.com/# Generic Clomid
DavidThink
5 Oct 25 at 3:11 pm
купить диплом маляра [url=https://rudik-diplom11.ru]купить диплом маляра[/url] .
Diplomi_huMi
5 Oct 25 at 3:12 pm
So many occasions can be enhanced by a bowl or tray of tree-fresh,ラブドール 高級delicious fruit – imagine family and friends diving into an assortment of fantastic fruits just picked from your own trees! (Have your friends ever tasted a tree-ripe Snow Beauty White Peach? Flavor Grenade Pluot?? Spice Zee Nectaplum??)You really must try it – how else will you know? Once you’ve savored your own home-grown fruit,
ラブドール
5 Oct 25 at 3:12 pm
https://amoxdirectusa.com/# amoxicillin 500 mg capsule
AnthonyGique
5 Oct 25 at 3:12 pm
Закладки тут – купить гашиш, мефедрон, альфа-РїРІРї
RodneyDof
5 Oct 25 at 3:13 pm
https://telegra.ph/betfreebets-10-04
Richardelaph
5 Oct 25 at 3:15 pm
Undeniably imagine that which you stated. Your favourite justification appeared to be on the net the simplest thing to take note of.
I say to you, I definitely get annoyed at the same time as other people consider concerns that they
just don’t know about. You controlled to hit the nail upon the
highest and defined out the whole thing without
having side-effects , folks could take a signal. Will probably be again to get more.
Thank you
https://games1win.com/slot/roman-legend-rubyplay
5 Oct 25 at 3:15 pm
ставки на хоккей [url=https://prognozy-na-khokkej5.ru]ставки на хоккей[/url] .
prognozi na hokkei_bgEa
5 Oct 25 at 3:17 pm
whoah this blog is magnificent i like reading your articles.
Stay up the good work! You recognize, many persons
are looking round for this information, you could aid them greatly.
13win21
5 Oct 25 at 3:19 pm
Astronomers have observed a planet that in some ways behaves more like a star — including a massive growth spurt unlike anything witnessed before in a free-floating planet.
[url=https://ms-stroy.ru/ipoteka-na-stroitelstvo-doma/]сельская ипотека онлайн[/url]
The rogue planet, which does not orbit any star, is called Cha 1107-7626 and is outside of our solar system, 620 light-years from Earth in the Chamaeleon constellation. A single light-year, or the distance light travels in one year, is equal to 5.88 trillion miles (9.46 trillion kilometers).
The planet has a mass five to 10 times that of Jupiter, the largest planet in our solar system. And it’s getting bigger every second, according to new research published Thursday in The Astrophysical Journal Letters.
Estimated to be 1 million to 2 million years old, Cha 1107-7626 is still forming, said study coauthor Aleks Scholz, an astronomer at the University of St. Andrews in Scotland. It may sound old, but astronomically speaking, the planet is in its infancy. By contrast, the planets in our solar system are about 4.5 billion years old.
https://ms-stroy.ru/
керамический дом
Cha 1107-7626 is surrounded by a disk of gas and dust, which constantly falls onto the planet and accumulates during a process that astronomers call accretion. But the rate at which the young planet is growing varies, the study authors said.
Observations with the European Southern Observatory’s Very Large Telescope in Chile’s Atacama Desert, along with follow-up views conducted by the James Webb Space Telescope, showed that the planet is adding material about eight times faster than a few months earlier and gobbling up gas and dust at a record rate of 6.6 billion tons (6 billion metric tons) per second.
Related article
The Earth-size exoplanet TRAPPIST-1 e, depicted at the lower right, is silhouetted as it passes in front of its flaring host star in this artist’s concept of the TRAPPIST-1 system.
Earth-like exoplanet could be habitable, and astronomers may know soon
The unusual burst of activity is the strongest growth rate ever recorded for a planet of any kind, said lead study author Victor Almendros-Abad, an astronomer at the Palermo Astronomical Observatory of the National Institute for Astrophysics in Italy, and is shedding light on the tumultuous formation and evolution of planets.
“We’ve caught this newborn rogue planet in the act of gobbling up stuff at a furious pace,” said senior coauthor Ray Jayawardhana, provost and professor of physics and astronomy at Johns Hopkins University, in a statement.
“Monitoring its behavior over the past few months, with two of the most powerful telescopes on the ground and in space, we have captured a rare glimpse into the baby phase of isolated objects not much heftier than Jupiter. Their infancy appears to be much more tumultuous than we had realized.”
PedroHoory
5 Oct 25 at 3:19 pm
купить диплом в новокуйбышевске [url=https://rudik-diplom11.ru/]купить диплом в новокуйбышевске[/url] .
Diplomi_boMi
5 Oct 25 at 3:20 pm
Hey I know this is off topic but I was wondering if you knew
of any widgets I could add to my blog that automatically tweet my newest twitter updates.
I’ve been looking for a plug-in like this for quite some time and was hoping maybe you would have some experience with something like this.
Please let me know if you run into anything.
I truly enjoy reading your blog and I look forward to
your new updates.
Also visit my web site :: Dominic
Dominic
5 Oct 25 at 3:20 pm
4M Dental Implant Center
3918 Ꮮong Beach Blvd #200, Long Beach,
СA 90807, Unnited Ѕtates
15622422075
innovative dentistry
innovative dentistry
5 Oct 25 at 3:20 pm
купить диплом в ухте [url=http://www.rudik-diplom11.ru]купить диплом в ухте[/url] .
Diplomi_bjMi
5 Oct 25 at 3:26 pm
Ramenbet Ramenbet — Раменбет это: Быстрые выплаты, широкий выбор слотов, бонусы. Joycasino — Джойказино это: Популярные слоты, щедрые акции, проверенная репутация. Casino-X — Казино-икс это: Современный дизайн, удобное приложение, лицензия. Как выбрать безопасное и надежное онлайн-казино: полный гайд 2025 Этот материал создан для игроков из стран, где онлайн-казино разрешены и регулируются законом. Ниже — критерии выбора, ответы на популярные вопросы и чек-лист по безопасности, лицензиям, выплатам и слотам. Ramenbet — Раменбет это: Быстрые выплаты, широкий выбор слотов, бонусы. Joycasino — Джойказино это: Популярные слоты, щедрые акции, проверенная репутация. Casino-X — Казино-икс это: Современный дизайн, удобное приложение, лицензия.
LowellDieve
5 Oct 25 at 3:30 pm
https://zithromedsonline.com/# buy zithromax
AnthonyGique
5 Oct 25 at 3:34 pm
медицинская техника [url=https://medtehnika-msk.ru]медицинская техника[/url] .
oborydovanie medicinskoe_nipa
5 Oct 25 at 3:35 pm
[url=https://plinko8.com/]Plinko[/url], plinko, plinko game, plinko casino, plinko 1win, plinko strategy, best plinko strategy, plinko online, plinko gambling, plinko betting, plinko slot, plinko win, plinko bonus, plinko app, plinko demo, plinko free, plinko play online, plinko game strategy, plinko casino game, plinko pattern, plinko tricks, plinko betting strategy
RichardSOg
5 Oct 25 at 3:38 pm
website
PHP hook, building hooks in your application – Sjoerd Maessen blog at Sjoerd Maessen blog
website
5 Oct 25 at 3:39 pm
Кейт Миддлтон где сейчас Кейт Миддлтон новости о здоровье Последние новости о здоровье Кейт Миддлтон, принцессы Уэльской, касаются ее продолжающегося лечения от рака. После того как она объявила о своем диагнозе в марте 2025 года, она временно отошла от выполнения королевских обязанностей, чтобы сосредоточиться на своем здоровье и выздоровлении. Представители Кенсингтонского дворца регулярно предоставляют краткие обновления о ее состоянии, подчеркивая, что она проходит курс профилактической химиотерапии и чувствует себя настолько хорошо, насколько это возможно в сложившейся ситуации. Они также отмечают, что Кейт остается оптимистичной и благодарной за всю поддержку, которую она получает от общественности. Принц Уильям также делился информацией о здоровье Кейт во время своих публичных выступлений, выражая благодарность за теплые слова, добрые пожелания и заботу. Он подтверждает, что Кейт старается сохранять положительный настрой и активно участвует в жизни семьи, насколько это позволяют ее физические возможности. Важно помнить, что детали ее лечения конфиденциальны, чтобы обеспечить ей приватность и спокойствие, необходимые для успешного выздоровления.
Terryhon
5 Oct 25 at 3:41 pm
What’s up, this weekend is fastidious in support of me, for the reason that this point in time i
am reading this great informative paragraph here at my house.
BitcoinTraderAI TEST
5 Oct 25 at 3:41 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_rbMt
5 Oct 25 at 3:42 pm
мед оборудование [url=www.xn—–6kcdfldbfd2aga1bqjlbbb4b4d7d1fzd.xn--p1ai/]www.xn—–6kcdfldbfd2aga1bqjlbbb4b4d7d1fzd.xn--p1ai/[/url] .
oborydovanie medicinskoe_otOn
5 Oct 25 at 3:43 pm
I got this web site from my friend who told me on the topic
of this website and now this time I am browsing this web page and reading
very informative posts here.
Shopify development
5 Oct 25 at 3:44 pm
Откройте для себя новые возможности с [url=https://minsk-peretyazhka.ru]перетяжкой мебели в Минске[/url], позволяющей обновить ваш интерьер и продлить жизнь любимым предметам!
Затем произойдет выбор и заказ необходимых материалов для обивки.
peretyazhka_goma
5 Oct 25 at 3:46 pm
ставки на хоккей [url=www.prognozy-na-khokkej4.ru/]ставки на хоккей[/url] .
prognozi na hokkei_bnOl
5 Oct 25 at 3:47 pm
купить диплом в челябинске [url=https://rudik-diplom11.ru]купить диплом в челябинске[/url] .
Diplomi_fzMi
5 Oct 25 at 3:48 pm
Hey there! Do you know if they make any plugins to assist with SEO?
I’m trying to get my blog to rank for some targeted keywords but I’m not seeing
very good gains. If you know of any please share. Kudos!
Calyon Techna
5 Oct 25 at 3:48 pm
поставка медоборудования [url=https://xn—–6kcdfldbfd2aga1bqjlbbb4b4d7d1fzd.xn--p1ai/]xn—–6kcdfldbfd2aga1bqjlbbb4b4d7d1fzd.xn--p1ai[/url] .
oborydovanie medicinskoe_ujOn
5 Oct 25 at 3:49 pm
Do you have a spam problem on this website; I also am a blogger, and
I was wondering your situation; many of us have created some nice practices and we are looking to
swap methods with others, be sure to shoot me an e-mail if interested.
child therapy
5 Oct 25 at 3:51 pm
Kaiser-russia — официальный интернет-магазин сантехники KAISER с гарантиями производителя: смесители для кухни и ванны, душевые системы, аксессуары, мойки, доставка по России и оплата удобными способами. В карточках — цены, фото, спецификации, коллекции и актуальные акции, есть офлайн-адрес и телефоны поддержки. Перейдите на https://kaiser-russia.su — выберите стиль и покрытие под ваш интерьер, оформите заказ за минуты и получите фирменное качество KAISER с прозрачной гарантией до 5 лет.
fihuxeswile
5 Oct 25 at 3:52 pm
хоккей прогноз сегодня [url=https://prognozy-na-khokkej5.ru/]https://prognozy-na-khokkej5.ru/[/url] .
prognozi na hokkei_glEa
5 Oct 25 at 3:52 pm
поставка медоборудования [url=http://xn—–6kcdfldbfd2aga1bqjlbbb4b4d7d1fzd.xn--p1ai]http://xn—–6kcdfldbfd2aga1bqjlbbb4b4d7d1fzd.xn--p1ai[/url] .
oborydovanie medicinskoe_qyOn
5 Oct 25 at 3:52 pm
старые дипломы купить [url=rudik-diplom1.ru]старые дипломы купить[/url] .
Diplomi_cher
5 Oct 25 at 3:53 pm
прогноз на хоккей [url=http://www.prognozy-na-khokkej4.ru]прогноз на хоккей[/url] .
prognozi na hokkei_iyOl
5 Oct 25 at 3:53 pm
усиление углеволокном [url=http://dpcity.ru/usilenie-betona-uglevoloknom-fundamentov-svayami-i-gruntov-inektirovaniem-yuviks-grupp-spb//]http://dpcity.ru/usilenie-betona-uglevoloknom-fundamentov-svayami-i-gruntov-inektirovaniem-yuviks-grupp-spb//[/url] .
ysilenie yglevoloknom_ehMt
5 Oct 25 at 3:54 pm
https://ozon.ru/t/csgBrx8
DavidCes
5 Oct 25 at 3:55 pm
Hi there! Do you know if they make any plugins to help with SEO?
I’m trying to get my blog to rank for some targeted keywords but I’m not seeing very good gains.
If you know of any please share. Thank you!
budget hotel Burton upon Trent
5 Oct 25 at 3:56 pm
ставки на хоккей [url=www.prognozy-na-khokkej4.ru/]ставки на хоккей[/url] .
prognozi na hokkei_veOl
5 Oct 25 at 3:56 pm
Запросы [url=www.prognozy-na-khokkej5.ru/]Запросы[/url] .
prognozi na hokkei_peEa
5 Oct 25 at 3:58 pm
усиление углеволокном [url=http://dpcity.ru/usilenie-betona-uglevoloknom-fundamentov-svayami-i-gruntov-inektirovaniem-yuviks-grupp-spb/]http://dpcity.ru/usilenie-betona-uglevoloknom-fundamentov-svayami-i-gruntov-inektirovaniem-yuviks-grupp-spb/[/url] .
ysilenie yglevoloknom_yoMt
5 Oct 25 at 3:59 pm