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!
блог интернет-маркетинга [url=http://statyi-o-marketinge7.ru/]http://statyi-o-marketinge7.ru/[/url] .
stati o marketinge _sskl
29 Oct 25 at 6:23 am
кракен vpn
кракен даркнет маркет
Henryamerb
29 Oct 25 at 6:26 am
частный seo оптимизатор [url=http://optimizaciya-i-seo-prodvizhenie-sajtov-moskva-1.ru/]частный seo оптимизатор[/url] .
optimizaciya i seo prodvijenie saitov moskva_xlPi
29 Oct 25 at 6:27 am
статьи про продвижение сайтов [url=http://statyi-o-marketinge7.ru/]статьи про продвижение сайтов[/url] .
stati o marketinge _kykl
29 Oct 25 at 6:27 am
Сначала коротко обозначим логику: каждый шаг должен иметь цель и измеримый результат, чтобы пациент и семья понимали, зачем мы делаем именно так.
Подробнее можно узнать тут – https://vyvod-iz-zapoya-moskva8.ru/vyvod-iz-zapoya-v-moskve-srochno
Danielkew
29 Oct 25 at 6:30 am
net seo [url=http://optimizaciya-i-seo-prodvizhenie-sajtov-moskva-1.ru]http://optimizaciya-i-seo-prodvizhenie-sajtov-moskva-1.ru[/url] .
optimizaciya i seo prodvijenie saitov moskva_chPi
29 Oct 25 at 6:33 am
кракен обмен
кракен онлайн
Henryamerb
29 Oct 25 at 6:34 am
kraken marketplace
kraken qr code
Henryamerb
29 Oct 25 at 6:34 am
статьи про seo [url=http://statyi-o-marketinge7.ru/]статьи про seo[/url] .
stati o marketinge _alkl
29 Oct 25 at 6:36 am
Kamagra livraison rapide en France: kamagra oral jelly – Kamagra sans ordonnance
RobertJuike
29 Oct 25 at 6:37 am
Intimatefriend noted
PHP hook, building hooks in your application – Sjoerd Maessen blog at Sjoerd Maessen blog
Intimatefriend noted
29 Oct 25 at 6:38 am
кракен сайт
kraken vk6
Henryamerb
29 Oct 25 at 6:40 am
http://farmaciavivait.com/# farmacia viva
Davidjealp
29 Oct 25 at 6:40 am
Эта информационная заметка содержит увлекательные сведения, которые могут вас удивить! Мы собрали интересные факты, которые сделают вашу жизнь ярче и полнее. Узнайте нечто новое о привычных аспектах повседневности и откройте для себя удивительный мир информации.
https://birlik-akmola.kz/?p=12640
WilliamBug
29 Oct 25 at 6:40 am
I have been browsing online more than 2 hours today, yet I never found any interesting article like
yours. It’s pretty worth enough for me. In my opinion, if all web owners and bloggers made
good content as you did, the internet will be a lot
more useful than ever before.
au88
29 Oct 25 at 6:40 am
The upcoming brand-neԝ physical space аt OMT promises immersive math experiences, triggering ⅼong-lasting love fоr the subject ɑnd motivation foг test achievements.
Ԍet ready fοr success in upcoming examinations with OMT Math Tuition’s proprietary curriculum, crеated to foster іmportant thinking ɑnd self-confidence in every trainee.
Ƭhе holistic Singapore Math method, ѡhich builds multilayered ⲣroblem-solving abilities,
highlights ᴡhy math tuition іs indispensable fօr mastering the curriculum аnd preparing for future careers.
Enriching primary education ԝith math tuition prepares students
fоr PSLE ƅy cultivating a growth statе of mind toѡards difficult
subjects liҝе proportion and changes.
Normal simulated Ⲟ Level examinations іn tuition setups replicate real ρroblems,
permitting students tߋ improve their method and minimize mistakes.
Tuition іn junior college math equips pupils
ԝith analytical techniques аnd possibility models vital fߋr analyzing data-driven concerns іn A Level
documents.
Ꭲhе exclusive OMT curriculum stands ɑpart bу integrating MOE syllabus aspects ԝith gamified quizzes and challenges t᧐
make finding out morе enjoyable.
OMT’ѕ online platform matches MOE syllabus оne, helping үoս tackle
PSLE mathematics easily ɑnd far ƅetter scores.
Ιn a hectic Singapore class, math tuition рrovides the slower, comprehensive xplanations required
tο develop ѕelf-confidence for exams.
Review my site :: Kaizenare math tuition
Kaizenare math tuition
29 Oct 25 at 6:41 am
rikvip1.click – Pages loaded fast, images appeared sharp, and formatting stayed consistent.
Bessie Capes
29 Oct 25 at 6:41 am
The Inheritance Games Canada: A thrilling mystery game where players unravel secrets, solve puzzles, and compete for a billionaire’s fortune. Perfect for fans of strategy and suspense: Barnes & Noble Inheritance Games
GabrielLyday
29 Oct 25 at 6:41 am
продвижение сайтов в москве [url=https://optimizaciya-i-seo-prodvizhenie-sajtov-moskva-1.ru]продвижение сайтов в москве[/url] .
optimizaciya i seo prodvijenie saitov moskva_hzPi
29 Oct 25 at 6:41 am
Galera, nao podia deixar de comentar no 4PlayBet Casino porque foi muito alem do que imaginei. A variedade de jogos e de cair o queixo: jogos ao vivo imersivos, todos funcionando perfeito. O suporte foi bem prestativo, responderam em minutos pelo chat, algo que vale elogio. Fiz saque em transferencia e o dinheiro entrou na mesma hora, ponto fortissimo. Se tivesse que criticar, diria que senti falta de ofertas recorrentes, mas isso nao estraga a experiencia. No geral, o 4PlayBet Casino e parada obrigatoria pra quem gosta de cassino. Eu ja voltei varias vezes.
kidi 4play|
neonfalcon88zef
29 Oct 25 at 6:42 am
маркетинговый блог [url=www.statyi-o-marketinge7.ru/]www.statyi-o-marketinge7.ru/[/url] .
stati o marketinge _ibkl
29 Oct 25 at 6:43 am
If you want to improve your knowledge only keep visiting this website
and be updated with the latest news posted here.
ankara kürtaj
29 Oct 25 at 6:43 am
Aw, this was a really good post. Taking a few minutes and
actual effort to produce a good article… but what can I say… I put things off a lot and never seem to get anything done.
نمایندگی تعمیرات بوتان
29 Oct 25 at 6:43 am
Заказать диплом о высшем образовании мы поможем. Купить диплом в Набережных Челнах – [url=http://diplomybox.com/kupit-diplom-naberezhnye-chelny/]diplomybox.com/kupit-diplom-naberezhnye-chelny[/url]
Cazrqgq
29 Oct 25 at 6:44 am
кракен даркнет маркет
кракен qr код
Henryamerb
29 Oct 25 at 6:46 am
купить диплом прораба [url=https://rudik-diplom14.ru/]купить диплом прораба[/url] .
Diplomi_pnea
29 Oct 25 at 6:47 am
Keep up the good job and producing in the group!
https://www.polskapraca.info
https://www.polskapraca.info
29 Oct 25 at 6:47 am
Ich habe einen totalen Hang zu SpinBetter Casino, es liefert ein Abenteuer voller Energie. Der Katalog ist reichhaltig und variiert, mit immersiven Live-Sessions. Der Service ist von hoher Qualitat, verfugbar rund um die Uhr. Die Transaktionen sind verlasslich, trotzdem die Offers konnten gro?zugiger ausfallen. Global gesehen, SpinBetter Casino ist absolut empfehlenswert fur Spieler auf der Suche nach Action ! Zusatzlich die Plattform ist visuell ein Hit, fugt Magie hinzu. Ein Pluspunkt ist die schnellen Einzahlungen, die Vertrauen schaffen.
spinbettercasino.de|
SpinMasterZ7zef
29 Oct 25 at 6:47 am
продвижение сайта франция [url=www.optimizaciya-i-seo-prodvizhenie-sajtov-moskva-1.ru]www.optimizaciya-i-seo-prodvizhenie-sajtov-moskva-1.ru[/url] .
optimizaciya i seo prodvijenie saitov moskva_wrPi
29 Oct 25 at 6:47 am
Откройте для себя идеальное решение для защиты от солнца с [url=https://avtomaticheskie-rulonnye-zhalyuzi.ru/]автоматические рулонные жалюзи с электроприводом +7 (499) 638-25-37[/url], которые удобно управляются одним движением.
Автоматические жалюзи рулонные
автоматические рулонные жалюзи стоимость прокарниз
29 Oct 25 at 6:48 am
Great work! This is the kind of information that are meant
to be shared across the web. Disgrace on Google for now not positioning this publish
upper! Come on over and seek advice from my web site .
Thanks =)
web page
29 Oct 25 at 6:48 am
classychoiceoutlet.shop – Great experience overall, will absolutely recommend to friends and family.
Stephania Legeyt
29 Oct 25 at 6:49 am
I am genuinely pleased to glance at this weblog posts which consists of plenty of
helpful data, thanks for providing such information.
bokep medan
29 Oct 25 at 6:49 am
маркетинг в интернете блог [url=www.statyi-o-marketinge7.ru]www.statyi-o-marketinge7.ru[/url] .
stati o marketinge _fqkl
29 Oct 25 at 6:49 am
https://midialmed.ru/effektivnye-metody-borby-s-hronicheskoj-bolyu-bez-medikamentov/
MartinNEK
29 Oct 25 at 6:50 am
I like the valuable info you provide in your articles.
I’ll bookmark your blog and check again here regularly.
I’m quite certain I’ll learn many new stuff right here!
Best of luck for the next!
Local drain pro
29 Oct 25 at 6:52 am
блог агентства интернет-маркетинга [url=www.statyi-o-marketinge7.ru]www.statyi-o-marketinge7.ru[/url] .
stati o marketinge _hkkl
29 Oct 25 at 6:52 am
Ich habe einen Narren gefressen an Cat Spins Casino, es ladt zu unvergesslichen Momenten ein. Die Spiele sind abwechslungsreich und fesselnd, mit traditionellen Tischspielen. Der Bonus ist wirklich stark. Der Service ist rund um die Uhr verfugbar. Zahlungen sind sicher und schnell, allerdings mehr Bonusoptionen waren top. Am Ende, Cat Spins Casino ist ein Highlight fur Casino-Fans. Zusatzlich die Oberflache ist glatt und benutzerfreundlich, und ladt zum Verweilen ein. Ein tolles Extra die vielfaltigen Wettmoglichkeiten, personliche Vorteile bereitstellen.
Einen Blick werfen|
sonicpowerik6zef
29 Oct 25 at 6:53 am
кракен онион
кракен онлайн
Henryamerb
29 Oct 25 at 6:54 am
Клубника Казино – это ваш шанс погрузиться
в увлекательный мир азартных игр и выиграть
щедрые призы. В Клубника Казино представлены
самые популярные игровые автоматы,
настольные игры и множество интересных live-игр с реальными дилерами.
В Клубника Казино мы гарантируем полную безопасность и прозрачность
всех процессов, чтобы ваши данные и средства
были в надежных руках.
Почему казино Клубника поддержка – лучший выбор
для азартных игроков? Мы предлагаем щедрые бонусы и акции, чтобы каждый игрок мог увеличить свои шансы
на победу и насладиться игрой.
Кроме того, мы обеспечиваем быстрые выводы средств и круглосуточную
поддержку, чтобы вы могли
сосредоточиться на игре.
Когда вам стоит начать играть
в Клубника Казино? Зарегистрируйтесь в Клубника Казино и получите
бонусы, которые сразу увеличат ваши шансы на победу.
Вот что вас ждет:
Щедрые бонусы и бесплатные спины для новых игроков.
Примите участие в наших турнирах и промо-акциях,
чтобы получить шанс выиграть
крупные денежные призы.
Каждый месяц мы обновляем наш ассортимент игр,
добавляя новые интересные слоты и настольные игры.
В Клубника Казино каждый момент игры может стать выигрышным для
вас.
клубника казино
29 Oct 25 at 6:54 am
kraken marketplace
kraken qr code
Henryamerb
29 Oct 25 at 6:54 am
[url=https://mirkeramiki.org/]коррекция стелек формтотикс[/url]
OSELEsoms
29 Oct 25 at 6:55 am
At Physio Reasoning in New York City, we’re assisting customers recognize the reality regarding peptide treatment.
Jackson
29 Oct 25 at 6:56 am
kraken обмен
kraken vk6
Henryamerb
29 Oct 25 at 6:59 am
блог о рекламе и аналитике [url=https://statyi-o-marketinge7.ru]https://statyi-o-marketinge7.ru[/url] .
stati o marketinge _pmkl
29 Oct 25 at 7:00 am
купить диплом института [url=https://rudik-diplom14.ru]купить диплом института[/url] .
Diplomi_fqea
29 Oct 25 at 7:00 am
I can’t get enough of Pinco, it’s built for big moments. The titles on offer are next-level, including crypto-friendly games. 100% up to $500 with bonus spins. Agents respond fast and friendly. The process is intuitive and quick, in rare cases a few extra spins would be dope. In short, Pinco is a must for serious players. Also the interface is intuitive and fast, which turns every game into an event. A huge plus are the secure crypto transfers, that drives participation.
Visit the platform|
brightbyteex4zef
29 Oct 25 at 7:02 am
технического аудита сайта [url=http://optimizaciya-i-seo-prodvizhenie-sajtov-moskva-1.ru]http://optimizaciya-i-seo-prodvizhenie-sajtov-moskva-1.ru[/url] .
optimizaciya i seo prodvijenie saitov moskva_hcPi
29 Oct 25 at 7:02 am
kraken onion
kraken qr code
Henryamerb
29 Oct 25 at 7:05 am
seo блог [url=statyi-o-marketinge7.ru]seo блог[/url] .
stati o marketinge _wgkl
29 Oct 25 at 7:07 am