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!
кракен vk3
кракен vk5
Henryamerb
29 Oct 25 at 8:33 am
торкретирование стен цена за м2 [url=https://torkretirovanie-1.ru/]https://torkretirovanie-1.ru/[/url] .
torkretirovanie_feen
29 Oct 25 at 8:33 am
An outstanding share! I’ve just forwarded this onto a co-worker who has been doing a little homework on this.
And he in fact bought me lunch because I discovered it for him…
lol. So let me reword this…. Thanks for the meal!! But yeah, thanks for spending time to talk about this matter here on your internet
site.
real money online slots
29 Oct 25 at 8:34 am
торкретирование бетона цена м2 [url=http://www.torkretirovanie-1.ru]http://www.torkretirovanie-1.ru[/url] .
torkretirovanie_feen
29 Oct 25 at 8:36 am
кракен Москва
kraken ios
Henryamerb
29 Oct 25 at 8:38 am
I all the time used to read paragraph in news
papers but now as I am a user of net so from now I am using
net for articles, thanks to web.
lừa đảo cambodia
29 Oct 25 at 8:38 am
Курсы по наращиванию https://schoollegoart.ru ресниц, архитектуре и ламинированию бровей/ресниц с нуля: теория + практика на моделях, стерильность, карта бровей, классика/2D–4D, составы и противопоказания. Материалы включены, мини-группы, сертификат, чек-листы и помощь с портфолио и стартом продаж.
AlbertChert
29 Oct 25 at 8:40 am
Avanafil senza ricetta: acquistare Spedra online – comprare medicinali online legali
RichardImmon
29 Oct 25 at 8:42 am
Spedra prezzo basso Italia: differenza tra Spedra e Viagra – acquistare Spedra online
ClydeExamp
29 Oct 25 at 8:42 am
Курсы по наращиванию https://schoollegoart.ru ресниц, архитектуре и ламинированию бровей/ресниц с нуля: теория + практика на моделях, стерильность, карта бровей, классика/2D–4D, составы и противопоказания. Материалы включены, мини-группы, сертификат, чек-листы и помощь с портфолио и стартом продаж.
AlbertChert
29 Oct 25 at 8:42 am
Oh man, mathematics serves аѕ ɑmong from the
extremely vital subjects іn Junior College,
assisting kids comprehend patterns ᴡhich remain crucial іn STEM
jobs afterwards ahead.
Yishun Innova Junior College merges strengths fοr digital literacy and management excellence.Upgraded centers promote innovation ɑnd lifelong knowing.
Diverse programs іn media and languages promote creativity ɑnd citizenship.
Community engagements develop compassion аnd skills.
Students Ьecome positive, tech-savvy leaders ready fօr thhe digital age.
Eunoia Junior College embodies tһе peak of contemporary instructional innovation,
housed іn a striking hіgh-rise school tһat effortlessly integrates comunal learning
ɑreas, green arеas, and advanced technological hubs t᧐ create an inspiring environment fօr collaborative
ɑnd experiential education. Thе college’s unique philosophy օf ” lovely thinking” motivates students
tо mix intellectual іnterest witһ kindness and ethical reasoning, supported Ьy dynamic scholastic programs іn the arts,
sciences, and interdisciplinary reseɑrch studies tһat promote
imaginative ρroblem-solving аnd forward-thinking. Equipped ᴡith top-tier facilities ѕuch as professional-grade carrying οut arts theaters, multimedia studios, ɑnd interactive science laboratories,
students аre empowered tο pursue theіr enthusiasms and develop remarkable skills іn a holistic
manner. Through strategic partnerships ѡith leading universities ɑnd market leaders, tһe college uѕes enriching chances fоr undergraduate-level гesearch study, internships,
аnd mentorship tһat bridge classroom knowing ѡith real-ѡorld
applications. Αѕ a result, Eunoia Junior College’ѕ students develop
іnto thoughtful, resistant leaders ᴡho aгe not ϳust academically accomplished
hоwever аlso deeply dedicated tⲟ contributing positively tօ a varied and ever-evolving international
society.
Hey hey, calm pom рi ρi, math гemains among of the leading disciplines in Junior College, laying base іn A-Level calculus.
Αpart to institution facilities, emphasize ѡith math to stop typical pitfalls including careless blunders
ɑt assessments.
Wah, mathematics serves аѕ the foundation stone of primary learning,
helping kids ԝith geometric reasoning tо design careers.
Hey hey, Singapore parents, mathematics гemains peгhaps
the extremely crucial primary discipline, fostering creativity іn problem-solving
for innovative jobs.
Math trains precision, reducing errors in future professional roles.
Ӏn addition beyond establishment resources,
concentrate սpon math in ordeг to prevent common mistakes sսch aѕ inattentive blunders ⅾuring exams.
Mums ɑnd Dads, fearful օf losing style engaged lah, robust primary math guides fоr improved STEM comprehension as well
ɑѕ tech aspirations.
Αlso visit my web blog – Compassvale Secondary School
Compassvale Secondary School
29 Oct 25 at 8:42 am
diskrete Lieferung per DHL: Kamagra 100mg bestellen – vitalpharma24
ThomasCep
29 Oct 25 at 8:43 am
кракен зеркало
кракен Россия
Henryamerb
29 Oct 25 at 8:44 am
kraken tor
кракен ios
Henryamerb
29 Oct 25 at 8:44 am
торкретирование [url=https://torkretirovanie-1.ru/]торкретирование[/url] .
torkretirovanie_ycen
29 Oct 25 at 8:45 am
Play The Password Game online in Canada! Test your creativity and problem-solving skills as you craft secure passwords with fun, unique challenges. Perfect for puzzle enthusiasts: The Password Game online Canada
GabrielLyday
29 Oct 25 at 8:47 am
comprare medicinali online legali: farmacia viva – Spedra prezzo basso Italia
ClydeExamp
29 Oct 25 at 8:47 am
Курсы по наращиванию https://schoollegoart.ru ресниц, архитектуре и ламинированию бровей/ресниц с нуля: теория + практика на моделях, стерильность, карта бровей, классика/2D–4D, составы и противопоказания. Материалы включены, мини-группы, сертификат, чек-листы и помощь с портфолио и стартом продаж.
AlbertChert
29 Oct 25 at 8:48 am
PRP-курс для косметологов плазмотерапия обучение в москве доказательная база, отбор пациентов, подготовка образца, техники введения (лицо, шея, кожа головы), сочетание с мезо/микронидлингом. Практика, рекомендации по фото/видео-фиксации, юридические формы, маркетинг услуги. Сертификат и кураторство.
ThomasTar
29 Oct 25 at 8:49 am
Помимо ставок на спорт, 1xbet предлагает массу других продуктов, которые будут
интересны азартным игрокам –
казино, покер, тотализатор, лотереи.
1хбет личный кабинет
29 Oct 25 at 8:51 am
Quality posts is the secret to attract the people to pay a quick visit the web site, that’s what this website
is providing.
마사지구인
29 Oct 25 at 8:51 am
Эта обзорная заметка содержит ключевые моменты и факты по актуальным вопросам. Она поможет читателям быстро ориентироваться в теме и узнать о самых важных аспектах сегодня. Получите краткий курс по современной информации и оставайтесь в курсе событий!
Нажмите, чтобы узнать больше – https://o-kubani.ru/vse-novosti/pogoda-na-kubani-dozhdi-teplo-do-25-i-tumany-v-koncze-marta-2025
Vincentorbit
29 Oct 25 at 8:52 am
Kamagra 100mg bestellen: vitalpharma24 – Kamagra online kaufen
ThomasCep
29 Oct 25 at 8:54 am
Этот текст призван помочь читателю расширить кругозор и получить практические знания. Мы используем простой язык, наглядные примеры и структурированное изложение, чтобы сделать обучение максимально эффективным и увлекательным.
Открыть полностью – https://covid.antibaro.gr/analysis/530
GregoryErade
29 Oct 25 at 8:54 am
торкретирование [url=www.torkretirovanie-1.ru]торкретирование[/url] .
torkretirovanie_ngen
29 Oct 25 at 8:55 am
Sildenafil générique: Kamagra livraison rapide en France – Kamagra oral jelly France
RichardImmon
29 Oct 25 at 8:55 am
В этом информативном тексте представлены захватывающие события и факты, которые заставят вас задуматься. Мы обращаем внимание на важные моменты, которые часто остаются незамеченными, и предлагаем новые перспективы на привычные вещи. Подготовьтесь к тому, чтобы быть поглощенным увлекательными рассказами!
Узнай первым! – https://www.cocodance.ch/img_0002
Anthonyvob
29 Oct 25 at 8:57 am
PRP-курс для косметологов обучение прп-терапии доказательная база, отбор пациентов, подготовка образца, техники введения (лицо, шея, кожа головы), сочетание с мезо/микронидлингом. Практика, рекомендации по фото/видео-фиксации, юридические формы, маркетинг услуги. Сертификат и кураторство.
ThomasTar
29 Oct 25 at 8:57 am
Ищете Ищете магазин швейных машин? Посетите сайт shveichel.ru – это крупнейший магазин швейных машин. В каталоге доступны бытовая и промышленная швейная техника, вязальные машины, ScanNCut плоттеры, гладильные доски и прессы, фурнитура, ткани, нитки и многое другое для рукоделия. Также доступны услуги сервисного центра: диагностика, ремонт с разборкой, замена комплектующих и профессиональная настройка швейных машин.
higishot
29 Oct 25 at 8:59 am
PRP-курс для косметологов prp терапия обучение доказательная база, отбор пациентов, подготовка образца, техники введения (лицо, шея, кожа головы), сочетание с мезо/микронидлингом. Практика, рекомендации по фото/видео-фиксации, юридические формы, маркетинг услуги. Сертификат и кураторство.
ThomasTar
29 Oct 25 at 8:59 am
Sildenafil générique: Kamagra sans ordonnance – Kamagra sans ordonnance
RobertJuike
29 Oct 25 at 9:01 am
Kamagra oral jelly France: Kamagra sans ordonnance – Kamagra 100mg prix France
RobertJuike
29 Oct 25 at 9:02 am
торкретирование стен цена [url=https://torkretirovanie-1.ru]https://torkretirovanie-1.ru[/url] .
torkretirovanie_laen
29 Oct 25 at 9:03 am
PRP-курс для косметологов плазмотерапия обучение доказательная база, отбор пациентов, подготовка образца, техники введения (лицо, шея, кожа головы), сочетание с мезо/микронидлингом. Практика, рекомендации по фото/видео-фиксации, юридические формы, маркетинг услуги. Сертификат и кураторство.
ThomasTar
29 Oct 25 at 9:05 am
Если вы ищете информацию о бонусах при регистрации, ознакомьтесь с наши рекомендации о видах вознаграждений; в одном из разделов материала естественно упомянут https://sushikim.ru/image/pgs/1xbet-besplatnuy-promokod-pri-registracii.html для получения приветственного бонуса. Мы объясняем, как указывать данные при регистрации и какие правила нужно выполнить для отыгрыша.
LouisIgnig
29 Oct 25 at 9:09 am
торкретирование бетона цена м2 [url=http://torkretirovanie-1.ru/]http://torkretirovanie-1.ru/[/url] .
torkretirovanie_gzen
29 Oct 25 at 9:11 am
Значит не туда стучишься!а ребята молодцы! https://nasha-shapka.ru съел примерно 10мг, чувствуется легкое расслабление и успокоение, каких то явных или ярких эффектов не наблюдается..
Aaronbamib
29 Oct 25 at 9:13 am
торкретирование стен цена за м2 [url=http://torkretirovanie-1.ru/]http://torkretirovanie-1.ru/[/url] .
torkretirovanie_sben
29 Oct 25 at 9:14 am
Kamagra livraison rapide en France: VitaHomme – Kamagra livraison rapide en France
RobertJuike
29 Oct 25 at 9:15 am
Your style is very unique compared to other folks I’ve read
stuff from. Many thanks for posting when you have the opportunity, Guess I’ll just bookmark this web site.
Nhà cái DR88
29 Oct 25 at 9:22 am
«Трезвый Маяк» — клиника экстренной и плановой наркологической помощи с круглосуточным выездом и возможностью госпитализации. Мы аккуратно стабилизируем состояние, снимаем интоксикацию и абстиненцию, готовим к кодированию и сопровождаем пациента до устойчивой ремиссии. Работаем анонимно: врач приезжает без опознавательных знаков, документы оформляются в нейтральной формулировке и только по запросу.
Детальнее – [url=https://narkologicheskaya-klinika-sergiev-posad8.ru/]где находится наркологическая клиника[/url]
RonnyCaure
29 Oct 25 at 9:22 am
Pretty nice post. I just stumbled upon your
weblog and wanted to say that I have really enjoyed surfing around your blog posts.
After all I will be subscribing to your feed and I hope you write again soon!
먹튀
29 Oct 25 at 9:22 am
pillole per disfunzione erettile: comprare medicinali online legali – acquistare Spedra online
ClydeExamp
29 Oct 25 at 9:23 am
differenza tra Spedra e Viagra: farmacia viva – farmacia viva
ClydeExamp
29 Oct 25 at 9:24 am
I’m not sure where you are getting your info, but good topic.
I needs to spend some time learning much more or understanding more.
Thanks for wonderful information I was looking for
this information for my mission.
تعمیرات یخچال آرچلیک
29 Oct 25 at 9:24 am
В этом обзорном материале представлены увлекательные детали, которые находят отражение в различных аспектах жизни. Мы исследуем непонятные и интересные моменты, позволяя читателю увидеть картину целиком. Погрузитесь в мир знаний и удивительных открытий!
Почему это важно? – https://nutricionplena.com/centro-de-distribucion-cedis-omnilife-en-mexico-donde-comprar-omnilife-en-mexico
JosephZet
29 Oct 25 at 9:26 am
торкретирование стен [url=https://torkretirovanie-1.ru/]торкретирование стен[/url] .
torkretirovanie_anen
29 Oct 25 at 9:27 am
https://vitahomme.com/# kamagra
Davidjealp
29 Oct 25 at 9:27 am
Этот обзор предлагает структурированное изложение информации по актуальным вопросам. Материал подан так, чтобы даже новичок мог быстро освоиться в теме и начать использовать полученные знания в практике.
Не упусти шанс – https://www.gowaytour.com/introducing-this-amazing-tour
RobertZek
29 Oct 25 at 9:27 am
FarmaciaViva: pillole per disfunzione erettile – pillole per disfunzione erettile
ClydeExamp
29 Oct 25 at 9:30 am