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!
Nightlife Events In Orlando, Fl Parties, Dances, & Extra
website (blogfreely.net)
blogfreely.net
7 Aug 25 at 4:50 am
Bangkok At Night Time 40 Things To Do + Photographs 2024 link (Rodger)
Rodger
7 Aug 25 at 4:50 am
London Nightlife: A Guide To The City’s Finest Bars And Clubs Sixes Cricket
Blog article – https://rentry.co/es6ibb4u,
https://rentry.co/es6ibb4u
7 Aug 25 at 4:50 am
Wow, awesome blog layout! How long have you been blogging for?
you make blogging look easy. The overall look of your web site is excellent,
as well as the content!
Feel free to visit my website :: découvrir le jeu ici
découvrir le jeu ici
7 Aug 25 at 4:56 am
data-vyhoda.online [url=https://data-vyhoda.online]https://data-vyhoda.online[/url] .
data-vyhoda.online_trSr
7 Aug 25 at 4:58 am
https://allmynursejobs.com/author/woodsmyramoon1810/
Nathanagoky
7 Aug 25 at 4:59 am
Врачи клиники «АнтиТокс» используют эффективные и проверенные временем препараты, которые помогают пациентам в кратчайшие сроки стабилизировать самочувствие и восстановить нормальную работу организма. В список основных препаратов входят:
Углубиться в тему – https://vyvod-iz-zapoya-novosibirsk0.ru/vyvod-iz-zapoya-na-domu-novosibirsk/
Williambax
7 Aug 25 at 4:59 am
Ich war anfangs kritisch, als ich von c2088.cn gehört habe.
Inzwischen existieren ja gefühlt tausende Anbieter,
also war ich erst mal vorsichtig. Trotzdem wollte ich den Bonus ohne Einzahlung mal testen, und siehe
da – war echt positiv überrascht. Direkt nach der Registrierung
bei Spinmama wurde ein Bonus freigeschaltet,
ohne Risiko. Die Seite läuft stabil, egal ob am PC oder mobil in der App.
Was mich zusätzlich überzeugt hat: Stammspieler werden ebenfalls belohnt.
Das ist definitiv ein Alleinstellungsmerkmal.
Ich hab Spinmama auf meine Favoritenliste gepackt. Wer
ein modernes, sicheres und lohnendes Casino sucht, sollte Spinmama einfach mal ausprobieren.
QD
7 Aug 25 at 5:03 am
RS88 – Trang cá cược hàng đầu khuyến mãi 88k,
link vào nhanh RS88.COM. Giao diện mượt, cập nhật xu hướng, cược mượt mà.
rs88 casino
7 Aug 25 at 5:03 am
Детоксикация может проводиться как по «мягкой», так и по ускоренной схеме. Используются инфузионные растворы, препараты для коррекции давления, поддержания работы сердца, печени и почек, противосудорожные и седативные средства. Все препараты подбираются строго индивидуально, с учётом состояния пациента. Капельница длится от двух до четырёх часов. На протяжении всей процедуры нарколог контролирует динамику, корректирует дозировки и следит за состоянием. После завершения лечения врач обязательно выдаёт подробные рекомендации по питанию, приёму витаминов и последующему наблюдению.
Получить дополнительную информацию – https://vyvod-iz-zapoya-noginsk5.ru/vyvod-iz-zapoya-stacionar-v-noginske
JohnnyDen
7 Aug 25 at 5:06 am
Just came across Vitrafoxin and it seems to be getting some buzz for
its focus on joint support and inflammation relief. I like that it claims to use natural ingredients,
but I’m curious about how effective it really is.
Has anyone actually tried it? Would be great to hear if it helped with
pain or mobility issues over time.
Vitrafoxin
7 Aug 25 at 5:07 am
lasix 100mg [url=https://fluidcarepharmacy.shop/#]FluidCare Pharmacy[/url] lasix online
Harryinapy
7 Aug 25 at 5:07 am
data-vyhoda.online [url=http://data-vyhoda.online/]http://data-vyhoda.online/[/url] .
data-vyhoda.online_lrSr
7 Aug 25 at 5:07 am
data-vyhoda.online [url=http://data-vyhoda.online]http://data-vyhoda.online[/url] .
data-vyhoda.online_kbSr
7 Aug 25 at 5:10 am
I’m curious to find out what blog platform you have been using?
I’m having some minor security issues with my latest website and I would like
to find something more safeguarded. Do you have any recommendations?
اعتراض به نمره آیلتس
7 Aug 25 at 5:17 am
Thanks for finally talking about > PHP hook, building hooks in your application – Sjoerd Maessen blog at
Sjoerd Maessen blog < Loved it!
water damage restoration service
7 Aug 25 at 5:22 am
Есть ситуации, когда вызов врача на дом становится не просто желателен, а жизненно необходим. Если зависимый человек не способен самостоятельно прекратить употребление алкоголя или наркотиков, а его самочувствие заметно ухудшается, необходимо незамедлительно обратиться за медицинской помощью. Поводом для вызова нарколога служат следующие опасные симптомы:
Получить больше информации – http://narcolog-na-dom-novosibirsk0.ru
Jeremyhubre
7 Aug 25 at 5:24 am
data-vyhoda.online [url=www.data-vyhoda.online]www.data-vyhoda.online[/url] .
data-vyhoda.online_iwSr
7 Aug 25 at 5:25 am
Эта публикация завернет вас в вихрь увлекательного контента, сбрасывая стереотипы и открывая двери к новым идеям. Каждый абзац станет для вас открытием, полным ярких примеров и впечатляющих достижений. Подготовьтесь быть вовлеченными и удивленными каждый раз, когда продолжите читать.
Смотрите также… – https://saudeenergize.store/hello-world
LouisGet
7 Aug 25 at 5:27 am
Далее начинается этап детоксикации — это основа безопасного и эффективного вывода из запоя. Используются капельницы с современными очищающими и поддерживающими препаратами, комплекс витаминов, препараты для поддержки печени, почек и сердечно-сосудистой системы. При необходимости назначаются средства для стабилизации психоэмоционального состояния, купирования судорог, нормализации сна и снижения тревожности.
Узнать больше – [url=https://vyvod-iz-zapoya-balashiha5.ru/]вывод из запоя на дому круглосуточно[/url]
LarryRek
7 Aug 25 at 5:33 am
data-vyhoda.online [url=data-vyhoda.online]data-vyhoda.online[/url] .
data-vyhoda.online_fpSr
7 Aug 25 at 5:34 am
It’s amazing in support of me to have jouer wanted dead or a wild en ligne
website, which is useful designed for my experience.
thanks admin
jouer wanted dead or a wild en ligne
7 Aug 25 at 5:37 am
Близкий человек в запое? Не ждите ухудшения. Обратитесь в клинику — здесь проведут профессиональный вывод из запоя с последующим восстановлением организма.
Подробнее можно узнать тут – [url=https://vyvod-iz-zapoya-ekaterinburg.ru/]вывод из запоя анонимно город екатеринбург[/url]
Michaelalona
7 Aug 25 at 5:37 am
excellent submit, very informative. I’m wondering why the other experts of this sector don’t notice this.
You must proceed your writing. I am confident, you’ve a huge readers’ base already!
Web Bülten - Sosyal İçerik Platformu
7 Aug 25 at 5:40 am
После обращения по телефону или через сайт оператор уточняет адрес, состояние пациента и срочность выезда. Врач прибывает в течение 1–2 часов, а в экстренных случаях — в течение часа. На месте специалист проводит первичный осмотр: измеряет давление, пульс, сатурацию, температуру, уточняет длительность запоя, сопутствующие заболевания, особенности реакции на лекарства.
Углубиться в тему – [url=https://vyvod-iz-zapoya-himki5.ru/]вывод из запоя вызов[/url]
CalvinAmark
7 Aug 25 at 5:41 am
https://odysee.com/@MccaffreyjunelifeheartAnitasweet6:cdfd7e6e4d3bffe35829ed54835a583d231a90ba?view=about
Nathanagoky
7 Aug 25 at 5:41 am
Женский журнал [url=http://ksusha.online]http://ksusha.online[/url] .
ksusha.online_fypr
7 Aug 25 at 5:42 am
Как выбрать и заказать экскурсию по Казани? Посетите сайт https://to-kazan.ru/tours/ekskursii-kazan и ознакомьтесь с популярными форматами экскурсий, а также их ценами. Все экскурсии можно купить онлайн. На странице указаны цены, расписание и подробные маршруты. Все программы сопровождаются сертифицированными экскурсоводами.
Hicotddaync
7 Aug 25 at 5:46 am
A class also inherits slot specifiers from its superclasses,
so the set of slots actually present in any object is the union of
all the slots specified in a class’s DEFCLASS form and those specified in all its superclasses.
For instance, money-market-account will inherit slots and behaviors for dealing
with checks from checking-account and slots and behaviors for computing interest from savings-account.
This will save you time and money on transportation costs.
Molly Sims, whom she considers a mentor, told New York
she thinks Kloss is the type of model who will still “do well at 30” because
of her classic look. Because behaviors are associated with a class
by defining generic functions and methods specialized on the class, DEFCLASS is responsible only for defining the
class as a data type. You’ll use the class name as the argument to MAKE-INSTANCE,
the function that creates new instances of user-defined classes.
Thus, methods specialized on different classes could end up manipulating the same slot when applied
to a class that extends those classes. The first balance is the name of the variable,
and the second is the name of the accessor function; they
don’t have to be the same. One of her first modelling stints was for
Abercrombie when she posed for the brand’s photography shot by Bruce Weber.
fruit machine
7 Aug 25 at 5:53 am
What’s up, this weekend is nice in support of me,
because this point in time i am reading this impressive educational post here at my residence.
اعتراض به مردودی کنکور ۱۴۰۴
7 Aug 25 at 5:57 am
купить диплом с занесением в реестр челябинск [url=www.arus-diplom31.ru]купить диплом с занесением в реестр челябинск[/url] .
Diplomi_jipl
7 Aug 25 at 6:06 am
Nice post. I used to be checking continuously this blog and I’m impressed!
Very helpful info particularly the last part 🙂 I care for such info a lot.
I was seeking this particular info for a very lengthy time.
Thanks and best of luck.
نحوه دریافت فیش بیمه تامین اجتماعی
7 Aug 25 at 6:08 am
When someone writes an article he/she maintains the image of a user in his/her mind that how a user can be aware
of it. So that’s why this paragraph is amazing.
Thanks!
rolet 303
7 Aug 25 at 6:10 am
Greetings! I know this is somewhat off topic but I was wondering if you knew
where I could get a captcha plugin for my comment form?
I’m using the same blog platform as yours and
I’m having difficulty finding one? Thanks a
lot!
memek basah
7 Aug 25 at 6:11 am
chiterskiy.ru [url=chiterskiy.ru]chiterskiy.ru[/url] .
chiterskiy.ru_hsma
7 Aug 25 at 6:12 am
Tizanidine 2mg 4mg tablets for sale [url=https://relaxmedsusa.com/#]safe online source for Tizanidine[/url] affordable Zanaflex online pharmacy
Harryinapy
7 Aug 25 at 6:17 am
Hi there! I could have sworn I’ve been to this web site before but after going through a few of the articles I realized it’s new to me.
Anyways, I’m certainly pleased I discovered it and I’ll be bookmarking it and checking back often!
https://justpaste.me/Y1jK1
7 Aug 25 at 6:18 am
https://imageevent.com/arjolaocanto/aeijj
Nathanagoky
7 Aug 25 at 6:24 am
Современные методы лечения при выводе из запоя включают как медикаментозную детоксикацию, так и психологическую реабилитацию. В Уфе наркологи используют капельничное введение лекарственных средств, которые помогают быстро вывести токсины, нормализовать обмен веществ и стабилизировать работу внутренних органов. Одновременно с этим проводится психологическая поддержка для снижения эмоционального стресса, связанного с запоем.
Получить дополнительную информацию – http://narcolog-na-dom-ufa0.ru/narkolog-na-dom-ufa-czeny/
Jamesswold
7 Aug 25 at 6:24 am
купить диплом ижевск с занесением в реестр [url=arus-diplom34.ru]купить диплом ижевск с занесением в реестр[/url] .
Priobresti diplom lubogo VYZa!_ovkn
7 Aug 25 at 6:25 am
Игровой портал [url=www.chiterskiy.ru/]www.chiterskiy.ru/[/url] .
chiterskiy.ru_kxma
7 Aug 25 at 6:26 am
лечение запоя тула
tula-narkolog002.ru
вывод из запоя круглосуточно
narkologiyatulaNeT
7 Aug 25 at 6:28 am
Этот увлекательный информационный материал подарит вам массу новых знаний и ярких эмоций. Мы собрали для вас интересные факты и сведения, которые обогатят ваш опыт. Откройте для себя увлекательный мир информации и насладитесь процессом изучения!
Почему это важно? – https://fnd.gr/pages/help
ThomasVutle
7 Aug 25 at 6:32 am
https://xn--d1arpf.xn--p1ai/forums/users/ucigep/
https://xn--d1arpf.xn--p1ai/forums/users/ucigep/
7 Aug 25 at 6:32 am
Сигналы, указывающие на потребность в наркологической помощи, часто игнорируются либо недооцениваются. Очень важно не пропустить тревожные симптомы, такие как:
Детальнее – https://narkologicheskaya-klinika-podolsk5.ru/
DouglasPap
7 Aug 25 at 6:37 am
Kenali TESLATOTO, situs slot demo gratis X5000 dari PG Soft & Pragmatic Play.
Tanpa perlu deposit, cukup klik dan mulai bermain, rasakan sensasi maxwin hari ini!
teslatoto demo slot
7 Aug 25 at 6:38 am
chiterskiy.ru [url=https://chiterskiy.ru/]https://chiterskiy.ru/[/url] .
chiterskiy.ru_ocma
7 Aug 25 at 6:38 am
I’ll right away snatch your rss feed as I can not find your e-mail subscription hyperlink or newsletter service.
Do you’ve any? Please permit me recognise so that I may just subscribe.
Thanks.
سفارش سئو تکنیکال - خدمات بهینه سازی فنی سایت
7 Aug 25 at 6:43 am
Игровой портал [url=http://chiterskiy.ru/]http://chiterskiy.ru/[/url] .
chiterskiy.ru_lema
7 Aug 25 at 6:48 am
купить диплом колледжа с занесением в реестр [url=https://www.arus-diplom31.ru]купить диплом колледжа с занесением в реестр[/url] .
Diplomi_bapl
7 Aug 25 at 6:50 am