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!
https://www.medtronik.ru/ узнайте, как получить приветственные бонусы и участвовать в акциях
Aaronawads
22 Oct 25 at 2:14 pm
모든 연령대가 즐길 수 있는 분당의 품격 있는 노래 문화!
프라이빗 룸을 갖춘 고급 가라오케, 세련된 룸싸롱, 편안한 노래방까지 다양한 공간에서 최상의 서비스와
분당가라오케
22 Oct 25 at 2:15 pm
Эта обзорная заметка содержит ключевые моменты и факты по актуальным вопросам. Она поможет читателям быстро ориентироваться в теме и узнать о самых важных аспектах сегодня. Получите краткий курс по современной информации и оставайтесь в курсе событий!
Посмотреть всё – https://consultant-seo.io/meilleurs-experts-seo
MauriceCam
22 Oct 25 at 2:15 pm
Very nice post. I just stumbled upon your blog and wished to say that I’ve really
enjoyed surfing around your blog posts. After all I’ll be subscribing to your feed and I hope you write again soon!
adameve promo code
22 Oct 25 at 2:15 pm
купить диплом архитектора [url=https://rudik-diplom7.ru]купить диплом архитектора[/url] .
Diplomi_jiPl
22 Oct 25 at 2:16 pm
купить проведенный диплом кого [url=http://frei-diplom3.ru]купить проведенный диплом кого[/url] .
Diplomi_inKt
22 Oct 25 at 2:18 pm
трансы Екатеринбург Телеграм: Проводник по Миру Трансгендерности в Городах России Telegram давно перестал быть просто мессенджером. Он превратился в многофункциональную платформу, где люди находят единомышленников, делятся информацией и организуют сообщества по интересам. Одним из таких направлений являются каналы, посвященные трансгендерной тематике. В российских городах, таких как Новосибирск, Екатеринбург, Воронеж, Волгоград и Челябинск, существуют Telegram-каналы, объединяющие транс-персон и тех, кто интересуется этим вопросом.
ChrisVOisa
22 Oct 25 at 2:19 pm
Статья знакомит с важнейшими моментами, которые сформировали наше общество. От великих изобретений до культурных переворотов — вы узнаете, как прошлое влияет на наше мышление, технологии и образ жизни.
Получить профессиональную консультацию – https://beacon-india.com/topology-study-in-solidworks-simulation-2019
Seymourlaf
22 Oct 25 at 2:19 pm
seo продвижение в москве [url=www.seo-prodvizhenie-reiting-kompanij.ru]seo продвижение в москве[/url] .
seo prodvijenie reiting kompanii_jcst
22 Oct 25 at 2:20 pm
купить сертификат специалиста [url=www.rudik-diplom2.ru/]купить сертификат специалиста[/url] .
Diplomi_sapi
22 Oct 25 at 2:21 pm
Новые смотреть сериалы всегда интригуют, уже нашли что-то стоящее?
смотреть сериалы
22 Oct 25 at 2:21 pm
to implement most of the bonuses it is necessary deposit minimum deposit, [url=https://timenny.com/1xbet-japan-login-your-guide-to-quick-access/]https://timenny.com/1xbet-japan-login-your-guide-to-quick-access/[/url], and necessary know about regulations and conditions in order understand requirements for wagering and other provisions.
AlexDoumb
22 Oct 25 at 2:21 pm
Superb site you have here but I was wanting to know if you knew of any discussion boards that cover the same
topics discussed here? I’d really love to be a part of community where I can get feed-back from other experienced people that share the same interest.
If you have any recommendations, please let me know. Thanks a lot!
비아그라 온라인 구매
22 Oct 25 at 2:22 pm
http://www.medtronik.ru получите максимум выгоды при старте игры
Aaronawads
22 Oct 25 at 2:23 pm
Где купить Закладку в Бакалые?Смотрите, нашел https://newmedtime.ru
– ценник адекватный, доставка оперативная. Кто-то пробовал у них? Насколько качественный товар?
Stevenref
22 Oct 25 at 2:24 pm
Link psg
ykusvpthz
22 Oct 25 at 2:24 pm
Nice post. I was checking continuously this blog and I am impressed!
Very helpful info particularly the last part 🙂 I care for such info much.
I was seeking this particular info for a very long time.
Thank you and good luck.
m98 สล็อต
22 Oct 25 at 2:25 pm
купить диплом в юрге [url=http://rudik-diplom2.ru]купить диплом в юрге[/url] .
Diplomi_lwpi
22 Oct 25 at 2:25 pm
раскрутка сайта в топ москва [url=http://seo-prodvizhenie-reiting-kompanij.ru/]http://seo-prodvizhenie-reiting-kompanij.ru/[/url] .
seo prodvijenie reiting kompanii_fpst
22 Oct 25 at 2:26 pm
где купить диплом техникума будьте [url=frei-diplom7.ru]где купить диплом техникума будьте[/url] .
Diplomi_fqei
22 Oct 25 at 2:27 pm
https://bluepeakmeds.shop/# how generic Viagra works in the body
LanceHek
22 Oct 25 at 2:27 pm
купить диплом колледжа с занесением в реестр в [url=http://frei-diplom5.ru/]купить диплом колледжа с занесением в реестр в[/url] .
Diplomi_gmPa
22 Oct 25 at 2:28 pm
https://riceowlscommunity.blogs.rice.edu/aviary-live/comment-page-407/#comment-21443
cprgted
22 Oct 25 at 2:31 pm
https://аксай.вывоз-мусора.org/
Tyronereumb
22 Oct 25 at 2:33 pm
купить диплом в феодосии [url=www.rudik-diplom3.ru/]www.rudik-diplom3.ru/[/url] .
Diplomi_mkei
22 Oct 25 at 2:33 pm
купить диплом с реестром киев [url=https://www.frei-diplom3.ru]https://www.frei-diplom3.ru[/url] .
Diplomi_ahKt
22 Oct 25 at 2:33 pm
Комплекс Термбург — это локация, где можно по-настоящему отдохнуть. Всё продумано для отдыха и восстановления: чистые парные и просторные сауны, бассейны с кристально чистой водой, термы и спа-зона с профессиональными массажистами. Атмосфера тишины и гармонии помогает перезагрузить мысли и наполниться силами уже после первого визита.
Особого внимания заслуживает [url=https://termburg.ru/services/]массаж шейно воротниковой зоны цена[/url] — это не просто косметическая процедура, а способ восстановить баланс кожи, улучшить микроциркуляцию и подарить коже свежесть и упругость. Опытные мастера используют проверенные приёмы — от лимфодренажного до тканевого массажа. Результат ощущается сразу — лёгкость, свежесть и ровный тон кожи.
Для тех, кто любит движение, работает [url=https://termburg.ru/services/]массаж лица услуга[/url] и сеансы для снятия напряжения в спине. Занятия проходят под руководством опытных тренеров, программы подходят для взрослых и детей. Здесь формируют правильную технику плавания, улучшают дыхание и делают процесс обучения лёгким и приятным. Баланс тела и разума — всё, что нужно, чтобы вернуться к себе обновлённым.
Leviomaza
22 Oct 25 at 2:34 pm
The $MTAUR token utility in unlocking special zones is what sets it apart from generic play-to-earn. Presale stage 1 savings are massive, up to 5x value. Team’s experience from top crypto projects adds credibility.
minotaurus presale
WilliamPargy
22 Oct 25 at 2:36 pm
seo агентство москва [url=https://seo-prodvizhenie-reiting-kompanij.ru]seo агентство москва[/url] .
seo prodvijenie reiting kompanii_ymst
22 Oct 25 at 2:36 pm
купить диплом в белгороде [url=https://rudik-diplom7.ru]купить диплом в белгороде[/url] .
Diplomi_oxPl
22 Oct 25 at 2:37 pm
как купить диплом о высшем образовании с занесением в реестр отзывы [url=frei-diplom3.ru]как купить диплом о высшем образовании с занесением в реестр отзывы[/url] .
Diplomi_xkKt
22 Oct 25 at 2:39 pm
купить диплом в уфе с реестром [url=www.frei-diplom5.ru/]www.frei-diplom5.ru/[/url] .
Diplomi_ewPa
22 Oct 25 at 2:40 pm
купить диплом в дербенте [url=http://rudik-diplom2.ru/]купить диплом в дербенте[/url] .
Diplomi_nppi
22 Oct 25 at 2:42 pm
J’adore la chaleur de VBet Casino, ca pulse avec une energie de casino digne d’un cratere. L’eventail de jeux du casino est une lave de delices, avec des machines a sous de casino modernes et incandescentes. Le support du casino est disponible 24/7, repondant en un eclair brulant. Les transactions du casino sont simples comme une braise, mais les offres du casino pourraient etre plus genereuses. Globalement, VBet Casino promet un divertissement de casino incandescent pour ceux qui cherchent l’adrenaline enflammee du casino ! Bonus le design du casino est un spectacle visuel brulant, ce qui rend chaque session de casino encore plus enflammee.
vbet netherlands|
fizzyglitterlemur9zef
22 Oct 25 at 2:43 pm
Link als
jpxiovsgd
22 Oct 25 at 2:44 pm
Galera, quero deixar registrado sobre o Bingoemcasa porque achei muito alem do que esperava. O site tem um ambiente divertido que lembra uma festa entre amigos. As salas de bingo sao movimentadas, e ainda testei blackjack e poker tambem, todos foram bem estaveis. O atendimento no chat foi rapido como nunca vi, o que ja me deixou satisfeito. As retiradas foram eficientes de verdade, inclusive testei cripto e funcionou perfeito. Se pudesse apontar algo, diria que senti falta de ofertas extras, mas nada que estrague a experiencia. Resumindo, o Bingoemcasa me conquistou. Ja me sinto parte da comunidade
bingoemcasa bet br|
mysticotter71zef
22 Oct 25 at 2:44 pm
купить диплом в копейске [url=http://rudik-diplom3.ru/]купить диплом в копейске[/url] .
Diplomi_xyei
22 Oct 25 at 2:46 pm
купить диплом с занесением в реестры [url=http://frei-diplom3.ru]купить диплом с занесением в реестры[/url] .
Diplomi_kmKt
22 Oct 25 at 2:47 pm
Hi there, I wish for to subscribe for this blog to obtain most recent updates, therefore where can i
do it please assist.
adameve coupon code
22 Oct 25 at 2:48 pm
Подробная пошаговая инструкция по активации бонусов и типам предложений — от фрибетов до подарков на День Рождения; в одном из абзацев естественно вставлена ссылка на 1хБет промокод на сегодня, дабы читатель мог быстро перейти к источнику. Статья также рассказывает о верификации и минимальных требованиях для вывода средств.
Anthonykit
22 Oct 25 at 2:48 pm
сео продвижение компания [url=www.seo-prodvizhenie-reiting-kompanij.ru/]сео продвижение компания[/url] .
seo prodvijenie reiting kompanii_lkst
22 Oct 25 at 2:48 pm
Публикация предлагает читателю не просто информацию, а инструменты для анализа и саморазвития. Мы стимулируем критическое мышление, предлагая различные точки зрения и призывая к самостоятельному поиску решений.
Обратиться к источнику – http://johjigroup.com/webeparsley-net/masayuki-toki/2016/12/01/tockys-instagram-6
Justincal
22 Oct 25 at 2:49 pm
http://hotel-golebiewski.phorum.pl/viewtopic.php?p=666448#666448
JoshuaGitty
22 Oct 25 at 2:49 pm
как купить легальный диплом [url=http://frei-diplom5.ru/]http://frei-diplom5.ru/[/url] .
Diplomi_wiPa
22 Oct 25 at 2:49 pm
диплом купить с занесением в реестр [url=https://www.frei-diplom1.ru]диплом купить с занесением в реестр[/url] .
Diplomi_tfOi
22 Oct 25 at 2:50 pm
купить диплом в златоусте [url=www.rudik-diplom7.ru]купить диплом в златоусте[/url] .
Diplomi_ruPl
22 Oct 25 at 2:51 pm
Amo a vibracao de PlayPIX Casino, e uma plataforma que pulsa com energia festiva. Ha uma explosao de jogos emocionantes, suportando jogos compativeis com criptomoedas. Eleva a diversao do jogo. O acompanhamento e impecavel, com suporte preciso e rapido. Os ganhos chegam sem demora, as vezes bonus mais variados seriam bem-vindos. Em resumo, PlayPIX Casino garante diversao a cada momento para jogadores em busca de adrenalina ! Acrescentando que a navegacao e simples e envolvente, aumenta o prazer de jogar. Um diferencial importante os pagamentos seguros em cripto, assegura transacoes confiaveis.
Obter informaГ§Гµes|
SambaRiserX9zef
22 Oct 25 at 2:52 pm
If some one needs expert view about blogging and site-building
then i recommend him/her to visit this web site, Keep up the nice job.
dewa scatter
22 Oct 25 at 2:54 pm
Ich bin komplett hin und weg von SpinBetter Casino, es ist eine Erfahrung, die wie ein Wirbelsturm pulsiert. Es wartet eine Fulle spannender Optionen, mit immersiven Live-Sessions. Die Agenten sind blitzschnell, immer parat zu assistieren. Die Transaktionen sind verlasslich, gelegentlich zusatzliche Freispiele waren ein Highlight. Zusammengefasst, SpinBetter Casino ist ein Muss fur alle Gamer fur Adrenalin-Sucher ! Daruber hinaus die Navigation ist kinderleicht, fugt Magie hinzu. Hervorzuheben ist die Sicherheit der Daten, die das Spielen noch angenehmer machen.
spinbettercasino.de|
Miscusimerle3zef
22 Oct 25 at 2:54 pm
Fiquei impressionado com BETesporte Casino, e uma plataforma que pulsa com emocao atletica. O catalogo e rico e diversificado, oferecendo jogos de mesa dinamicos. 100% ate R$600 + apostas gratis. O acompanhamento e impecavel, garantindo atendimento de alto nivel. Os pagamentos sao seguros e fluidos, as vezes ofertas mais generosas dariam um toque especial. No geral, BETesporte Casino oferece uma experiencia inesquecivel para amantes de apostas esportivas ! Vale destacar o design e moderno e dinamico, tornando cada sessao mais competitiva. Um diferencial importante as opcoes variadas de apostas esportivas, proporciona vantagens personalizadas.
Aprender os detalhes|
FutebolFogoM4zef
22 Oct 25 at 2:54 pm