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!
I was excited to uncover this website. I want to to thank you for
your time for this particularly wonderful read!! I definitely loved every bit of it and I
have you saved to fav to look at new information in your site.
Rola Takizawa
14 Sep 25 at 12:37 pm
В первые часы важно не «залить» пациента растворами, а корректно подобрать темп и состав с учётом возраста, массы тела, артериального давления, лекарственного фона (антигипертензивные, сахароснижающие, антиаритмические препараты) и переносимости. Именно поэтому мы не отдаём лечение на откуп шаблонам — каждая схема конструируется врачом на месте, а эффективность оценивается по понятным метрикам.
Получить дополнительную информацию – [url=https://vyvod-iz-zapoya-v-ryazani14.ru/]www.domen.ru[/url]
Jameszinee
14 Sep 25 at 12:38 pm
Ich bin suchtig nach Trickz Casino, es pulsiert mit einer verhexten Casino-Energie. Die Auswahl im Casino ist ein echtes Hexenwerk, mit Live-Casino-Sessions, die wie ein Zaubertrick funkeln. Der Casino-Support ist rund um die Uhr verfugbar, antwortet blitzschnell wie ein magischer Funke. Der Casino-Prozess ist klar und ohne Tauschung, ab und zu mehr Casino-Belohnungen waren ein zauberhafter Gewinn. Zusammengefasst ist Trickz Casino eine Casino-Erfahrung, die wie ein Zaubertrick glanzt fur Fans von Online-Casinos! Ubrigens die Casino-Plattform hat einen Look, der wie ein magischer Zirkus leuchtet, den Spielspa? im Casino auf ein magisches Niveau hebt.
trickz casino erfahrungen|
zanyglitterbadger8zef
14 Sep 25 at 12:39 pm
Drugs prescribing information. What side effects can this medication cause?
how to get generic lyrica no prescription
Actual what you want to know about medicines. Read information now.
how to get generic lyrica no prescription
14 Sep 25 at 12:41 pm
купить диплом института высшего образования [url=https://www.educ-ua18.ru]купить диплом института высшего образования[/url] .
Diplomi_gdPi
14 Sep 25 at 12:42 pm
авиатор игра на деньги [url=http://1win12011.ru]авиатор игра на деньги[/url]
1win_wjOl
14 Sep 25 at 12:42 pm
Fantastic beat ! I wish to apprentice while you amend your web site, how can i subscribe for a blog site?
The account helped me a acceptable deal. I had been a
little bit acquainted of this your broadcast provided bright clear concept
game bài đổi thưởng
14 Sep 25 at 12:43 pm
Узнайте основные факты о JAECOO Авторусь Бутово — партнёр бренда в столице: актуальные модели, выгодные условия, сервис и запчасти от производителя! Перейдите на [url=https://jaecoo-avtorussbutovo.ru]https://jaecoo-avtorussbutovo.ru[/url] и посмотрите с ассортиментом моделей. Хотите пробную поездку или финансирование? — автосалон предлагает рассрочку 0%, обмен Trade-In и гарантированное обслуживание. Ищете JAECOO — здесь найдёте передовые разработки и экспертную помощь.
Spravkihnb
14 Sep 25 at 12:44 pm
J’adore la chaleur de VBet Casino, c’est un casino en ligne qui jaillit comme un volcan en furie. Les options de jeu au casino sont riches et enflammees, avec des machines a sous de casino modernes et incandescentes. Le service client du casino est une torche d’efficacite, avec une aide qui jaillit comme une flamme. Les paiements du casino sont securises et fluides, quand meme des bonus de casino plus frequents seraient brulants. Globalement, VBet Casino c’est un casino a explorer sans tarder pour les amoureux des slots modernes de casino ! Par ailleurs l’interface du casino est fluide et eclatante comme un cratere en fusion, ce qui rend chaque session de casino encore plus enflammee.
vbet change to decimal|
fizzyglitterlemur9zef
14 Sep 25 at 12:48 pm
can i order generic coversyl online
can i buy generic coversyl without rx
14 Sep 25 at 12:50 pm
Прозрачная маршрутизация помогает семье и самому пациенту понимать, почему выбирается именно данный формат — выезд на дом, амбулаторная помощь, дневной стационар или круглосуточное наблюдение. Таблица ниже иллюстрирует подход клиники к первым 24 часам.
Изучить вопрос глубже – [url=https://narkologicheskaya-klinika-rostov-na-donu14.ru/]лечение в наркологической клинике ростов-на-дону[/url]
Jackiemoips
14 Sep 25 at 12:54 pm
Мы готовы предложить документы учебных заведений, которые расположены на территории всей Российской Федерации. Купить диплом университета:
[url=http://rightlane.beparian.com/employer/ukrdiplom/]купить аттестат за 11 класс с занесением в реестр[/url]
Diplomi_wfPn
14 Sep 25 at 12:55 pm
Really helpful read, I have been searching for engraved bracelets.
I just discovered Onecklace UK and they have
cool name chains that are worth checking out.
Might help someone here looking for gift ideas.
buy personalized jewelry
14 Sep 25 at 12:58 pm
бк 1win официальный сайт [url=https://www.1win12011.ru]https://www.1win12011.ru[/url]
1win_etOl
14 Sep 25 at 1:00 pm
After I originally left a comment I appear to have clicked the -Notify
me when new comments are added- checkbox and now whenever a comment is added I receive 4
emails with the same comment. There has to be an easy method you can remove me from that
service? Cheers!
вебсайт
14 Sep 25 at 1:02 pm
диплом ссср купить недорого [url=http://educ-ua18.ru/]http://educ-ua18.ru/[/url] .
Diplomi_qpPi
14 Sep 25 at 1:03 pm
https://curabharatusa.shop/# drugs online
JeremyBip
14 Sep 25 at 1:05 pm
Выбор техники зависит от клинической картины, переносимости препаратов, психоэмоционального состояния и горизонта планируемой трезвости. Таблица ниже помогает сориентироваться в ключевых различиях — врач подробно разберёт нюансы на очной консультации.
Узнать больше – https://kodirovanie-ot-alkogolizma-vidnoe7.ru/kodirovanie-ot-alkogolizma-ceny-v-vidnom/
JeremyTEF
14 Sep 25 at 1:06 pm
купить диплом в одессе цены [url=http://educ-ua1.ru/]купить диплом в одессе цены[/url] .
Diplomi_qiei
14 Sep 25 at 1:07 pm
В «РостовМедЦентре» лечение начинается с подробной оценки факторов риска и мотивации. Клиническая команда анализирует стаж употребления, тип вещества, эпизоды срывов, соматический фон, лекарства, которые пациент принимает постоянно, и уровень социальной поддержки. Уже на первой встрече составляется «дорожная карта» на ближайшие 72 часа: диагностический минимум, объём медицинских вмешательств, пространство для психологической работы и точки контроля. Безопасность — не абстракция: скорости инфузий рассчитываются в инфузомате, седацию подбирают по шкалам тревоги и с обязательным контролем сатурации, а лекарственные взаимодействия сверяет клинический фармаколог. Пациент получает прозрачные цели на день, на неделю и на месяц — без обещаний мгновенных чудес и без стигмы.
Детальнее – [url=https://narkologicheskaya-klinika-rostov-na-donu14.ru/]наркологическая клиника в ростове-на-дону[/url]
Jackiemoips
14 Sep 25 at 1:10 pm
купить диплом образца ссср [url=https://educ-ua18.ru]https://educ-ua18.ru[/url] .
Diplomi_hgPi
14 Sep 25 at 1:10 pm
Hello it’s me, I am also visiting this web page daily, this website is truly good and the users are really sharing
fastidious thoughts.
https://duanju.meiwang360.com/sethpedersen0
14 Sep 25 at 1:15 pm
Мы можем предложить документы любых учебных заведений, которые расположены в любом регионе РФ. Приобрести диплом ВУЗа:
[url=http://fittact.vip/read-blog/929_skolko-stoit-kupit-attestat-11-klassa.html/]купить аттестат егэ 11 класс[/url]
Diplomi_mbPn
14 Sep 25 at 1:16 pm
http://truenorthpharm.com/# canadian pharmacy checker
CarlosPreom
14 Sep 25 at 1:19 pm
puoi acquistare le pillole di augmentin generico
posso ordinare augmentin economico online
14 Sep 25 at 1:21 pm
Ожидаемый результат
Изучить вопрос глубже – [url=https://vyvod-iz-zapoya-noginsk7.ru/]vyvod-iz-zapoya-deshevo[/url]
Richardbug
14 Sep 25 at 1:25 pm
Rainbet
GeraldMug
14 Sep 25 at 1:25 pm
Новости Украины https://status.net.ua объективная информация о событиях страны. Политика, экономика, региональные новости, спорт и культура. Читайте актуальные материалы каждый день.
PedroSeige
14 Sep 25 at 1:25 pm
«СпецДорТрак» — поставщик запчастей для дорожной, строительной и спецтехники с доставкой по РФ. В наличии позиции для ЧТЗ Т-130, Т-170, Б-10, грейдеров ЧСДМ ДЗ-98/143/180, ГС 14.02/14.03, техники на базе К 700 с двигателями ЯМЗ/Тутай, МТЗ, ЮМЗ, Урал, КРАЗ, МАЗ, БЕЛАЗ, а также ЭКГ, ДЭК, РДК. Карданные валы, включая изготовление по размерам. Подробнее на https://trak74.ru/ — свой цех ремонта, оперативная отгрузка, помощь в подборе и заказ под требуемые спецификации.
Sojajamrag
14 Sep 25 at 1:26 pm
мостбет лицензия [url=www.mostbet12013.ru]www.mostbet12013.ru[/url]
mostbet_oqka
14 Sep 25 at 1:27 pm
Новостной портал https://mediateam.com.ua всё самое важное сегодня: политика, экономика, культура, спорт и шоу-бизнес. Лента новостей, репортажи и аналитические материалы каждый день.
Elishafopsy
14 Sep 25 at 1:27 pm
Новости Украины и мира https://mostmedia.com.ua политика, экономика, культура, спорт и общество. Свежие события, аналитика и репортажи. Будьте в курсе главных новостей в режиме онлайн 24/7.
RobertZes
14 Sep 25 at 1:27 pm
https://truenorthpharm.shop/# canada pharmacy online
JeremyBip
14 Sep 25 at 1:27 pm
acheter de l’prozac sans ordonnance
coГ»t de l'prozac
14 Sep 25 at 1:28 pm
1win букмекерская контора бонусы [url=1win12013.ru]1win12013.ru[/url]
1win_giPa
14 Sep 25 at 1:31 pm
Необходимо кодирование? реабилитационный центр Хабаровск современные методы, конфиденциальность и поддержка специалистов. Помогаем избавиться от зависимости и вернуться к здоровой жизни.
zelenorgad-rehab-33
14 Sep 25 at 1:31 pm
Наркологическая помощь в Раменском в клинике «Возрождение» — это быстрый выезд профильного врача, безопасная детокс-терапия и полноценные программы восстановления без постановки на учёт. Мы работаем 24/7, аккуратно стабилизируем состояние на дому или принимаем в стационаре, подбираем лечение с учётом возраста, сопутствующих заболеваний и текущих анализов. Уже при первом обращении координатор уточняет симптомы, оценивает риски, предлагает ближайшее окно выезда и объясняет, как подготовиться к визиту. Наша задача — не временно приглушить симптомы, а выстроить путь к устойчивой ремиссии и вернуть пациенту контроль над жизнью, при этом сохраняя конфиденциальность каждого шага.
Подробнее – [url=https://narkologicheskaya-pomoshch-ramenskoe7.ru/]kruglosutochnaya-narkologicheskaya-pomoshch[/url]
LarryMub
14 Sep 25 at 1:31 pm
интернет домашний санкт-петербург
inernetvkvartiru-spb006.ru
провайдеры в санкт-петербурге по адресу проверить
internetelini
14 Sep 25 at 1:32 pm
https://list.ly/maryldiwcc
Enfrentar un test antidoping puede ser un momento critico. Por eso, existe una solucion cientifica creada con altos estandares.
Su composicion eficaz combina nutrientes esenciales, lo que prepara tu organismo y disimula temporalmente los marcadores de alcaloides. El resultado: una prueba sin riesgos, lista para pasar cualquier control.
Lo mas interesante es su ventana de efectividad de 4 a 5 horas. A diferencia de detox irreales, no promete limpiezas magicas, sino una solucion temporal que te respalda en situaciones criticas.
Miles de trabajadores ya han validado su discrecion. Testimonios reales mencionan paquetes 100% confidenciales.
Si quieres proteger tu futuro, esta formula te ofrece tranquilidad.
JuniorShido
14 Sep 25 at 1:32 pm
1vin зеркало [url=https://www.1win12010.ru]https://www.1win12010.ru[/url]
1win_qnEl
14 Sep 25 at 1:35 pm
Наркологическая клиника в Краснодаре предоставляет комплекс медицинских услуг, направленных на лечение алкогольной и наркотической зависимости, а также помощь при острых состояниях, связанных с интоксикацией организма. Основная задача специалистов заключается в оказании экстренной и плановой помощи пациентам, нуждающимся в выводе из запоя, детоксикации и реабилитации. Выбор правильного учреждения является ключевым условием для успешного выздоровления и предотвращения рецидивов.
Подробнее можно узнать тут – [url=https://narkologicheskaya-klinika-krasnodar14.ru/]наркологическая клиника клиника помощь краснодар[/url]
KeithRusty
14 Sep 25 at 1:36 pm
мостбет андроид [url=mostbet12010.ru]мостбет андроид[/url]
mostbet_svPt
14 Sep 25 at 1:37 pm
Excellent post. I was checking constantly this blog and I’m impressed!
Very useful information specifically the last part 🙂 I care for such info a lot.
I was looking for this certain info for a long time.
Thank you and good luck.
Arron
14 Sep 25 at 1:37 pm
Мы можем предложить документы учебных заведений, расположенных на территории всей Российской Федерации. Купить диплом любого ВУЗа:
[url=http://pgonline.ru/forums/index.php?topic=148294.new#new/]купить аттестат украины за 11[/url]
Diplomi_djPn
14 Sep 25 at 1:40 pm
купить диплом в полтаве [url=http://educ-ua1.ru/]http://educ-ua1.ru/[/url] .
Diplomi_csei
14 Sep 25 at 1:41 pm
купить диплом старого образца ссср [url=https://educ-ua18.ru/]https://educ-ua18.ru/[/url] .
Diplomi_izPi
14 Sep 25 at 1:42 pm
мостбет кыргызстан [url=http://mostbet12012.ru]http://mostbet12012.ru[/url]
mostbet_hvSl
14 Sep 25 at 1:44 pm
Срок действия (ориентир)
Подробнее – [url=https://kodirovanie-ot-alkogolizma-vidnoe7.ru/]medicinskij-centr-kodirovanie-ot-alkogolizma[/url]
JeremyTEF
14 Sep 25 at 1:47 pm
сайты для ставок [url=https://1win12007.ru]https://1win12007.ru[/url]
1win_thpn
14 Sep 25 at 1:48 pm
Откройте для себя удобный онлайн-кинотеатр с подборкой свежих премьер и проверенной классики. Наслаждайтесь Full HD и находите кино под настроение благодаря умным рекомендациям без лишних действий. Ищете лучшие ужасы онлайн? Переходите на kinospecto.online и начните вечер с идеального выбора. С любого устройства — быстрая загрузка, закладки и история просмотров делают просмотр максимально удобным. Оформите подписку и смотрите больше, не тратя время на бесконечные поиски.
mibosBaria
14 Sep 25 at 1:48 pm