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=https://vyvod-iz-zapoya-volgograd00.ru/]нарколог на дом вывод из запоя на дому[/url]
WilliamWheew
16 Jul 25 at 4:53 pm
Кодирование основано на блокировке механизмов зависимости на биохимическом и поведенческом уровнях. Медикаментозные методы включают введение препаратов пролонгированного действия, которые нарушают метаболизм этанола: при попытке выпить даже небольшую дозу алкоголь вызывает выражённые неприятные реакции, что психологически отвращает от новой пробы спиртного. Психотерапевтические техники, такие как гипноз или метод Довженко, направлены на переустановку подсознательных программ, удаление эмоционального влечения к алкоголю и укрепление мотивации к здоровому образу жизни. Аппаратные методики (электроимпульсная стимуляция, транскраниальная микрополяризация) воздействуют на нейроны, участвующие в развитии зависимости, снижая их активность и уменьшая физиологический дискомфорт. В «Орион-Клиник» часто используют комбинированные программы: сначала проводится детоксикация организма, затем вводится медикаментозное средство, после чего реализуется психотерапевтический блок влияния на подсознание.
Подробнее можно узнать тут – [url=https://kodirovanie-ot-alkogolizma-pushkino4.ru/]centr kodirovaniya ot alkogolizma[/url]
Rickeyfex
16 Jul 25 at 5:03 pm
После стабилизации назначаются препараты, снижающие влечение к алкоголю, нормализующие работу нервной системы и улучшающие общее самочувствие. К методам кодирования относятся уколы, вшивание препаратов, аппаратные методики и психотерапевтические техники. Врач всегда индивидуально подбирает программу — с учётом предыдущего опыта, наличия хронических болезней, особенностей организма.
Исследовать вопрос подробнее – https://lechenie-alkogolizma-vidnoe4.ru/lechenie-alkogolizma-na-domu-v-vidnom/
MichaelCiz
16 Jul 25 at 5:04 pm
После оформления заявки по телефону или на сайте оператор уточняет адрес и текущее состояние пациента. В критических ситуациях врач может прибыть в течение 60 минут, в стандартном режиме — за 1–2 часа. На месте проводится сбор анамнеза и оценка жизненных показателей: артериального давления, пульса, сатурации и температуры тела. Затем выбирается оптимальный протокол детоксикации — «мягкий» метод для постепенного выведения токсинов или экспресс-методика при острой интоксикации. Процедура капельного введения комбинированного раствора длится от двух до четырёх часов: специалист контролирует состояние пациента, корректирует дозировки и при необходимости вводит корригирующие препараты. По окончании врач оставляет детальный план поддерживающей терапии, включающий рекомендации по питанию, приёму сорбентов и витаминов, а также график повторных осмотров.
Получить дополнительную информацию – [url=https://narkolog-na-dom-ramenskoe4.ru/]вызов нарколога на дом[/url]
Charlesonemn
16 Jul 25 at 5:04 pm
ザオプション(theoption)で広がるバイナリーオプションの可能性
ザオプション(theoption)は、初心者から経験者まで幅広く利用されているバイナリーオプション取引プラットフォームです。最短30秒の高速取引や高いペイアウト率が魅力で、スマホ対応により外出先からも簡単に操作可能です。リスク管理をしながら効率的に資産運用ができる点が、多くのトレーダーに支持されています。詳細や最新情報は explorejapan.jp をご覧ください。
https://explorejapan.jp/
Fobertsax
16 Jul 25 at 5:04 pm
online apotheek zonder recept: pharmacy online – medicatie online
Altonjah
16 Jul 25 at 5:15 pm
https://zorgpakket.shop/# online medicijnen bestellen met recept
WilliamNog
16 Jul 25 at 5:16 pm
verzorgingsproducten apotheek: medicijn – mijn medicijn bestellen
Kennethrip
16 Jul 25 at 5:22 pm
Good day! Would you mind if I share your blog with my twitter group?
There’s a lot of people that I think would really enjoy your content.
Please let me know. Cheers
My web blog: situs judi togel online
situs judi togel online
16 Jul 25 at 5:29 pm
1win tennis mərcləri [url=www.1win3043.com]1win tennis mərcləri[/url]
1win_drEt
16 Jul 25 at 5:30 pm
масляный трансформатор купить [url=https://maslyanie-transformatory-kupit2.ru]https://maslyanie-transformatory-kupit2.ru[/url] .
maslyanie transformatori kypit_zsOn
16 Jul 25 at 5:33 pm
Сразу после поступления вызова специалист прибывает на дом для проведения первичного осмотра. На данном этапе нарколог:
Исследовать вопрос подробнее – https://narcolog-na-dom-ryazan00.ru/vyzov-narkologa-na-dom-ryazan/
MichaelTolve
16 Jul 25 at 5:39 pm
Оформиление дипломов ВУЗов по всей Украине — с печатями, подписями, приложением и возможностью архивной записи (по запросу).
Документ максимально приближен к оригиналу и проходит визуальную проверку.
Мы гарантируем, что в случае проверки документа, подозрений не возникнет.
– Конфиденциально
– Доставка 3–7 дней
– Любая специальность
Уже более 3910 клиентов воспользовались услугой — теперь ваша очередь.
[url=http://diplomykupit6.ru/]Высшее образование купить диплом с занесением[/url] — ответим быстро, без лишних формальностей.
Kennethfiz
16 Jul 25 at 5:42 pm
экстренный вывод из запоя краснодар
narkolog-krasnodar004.ru
вывод из запоя круглосуточно
zapojkrasnodarNeT
16 Jul 25 at 5:43 pm
Вся процедура проходит под полным контролем врача и занимает от 40 минут до 2 часов. Пациенту и его родственникам даются рекомендации по дальнейшему лечению и профилактике повторных запоев.
Изучить вопрос глубже – http://kapelnica-ot-zapoya-moskva00.ru
MichaelJaX
16 Jul 25 at 5:46 pm
askorbinsyre pulver apotek: Trygg Med – middel mot klegg apotek
Kennethrip
16 Jul 25 at 5:51 pm
Thanks in favor of sharing such a fastidious thought, piece of writing is
fastidious, thats why i have read it entirely
คลิปหลุดวีเค
16 Jul 25 at 5:52 pm
частный пансионат для престарелых
pansionat-msk002.ru
пансионат для пожилых в москве
izzapoyakrasnodarNeT
16 Jul 25 at 5:52 pm
apotek gratis frakt [url=https://snabbapoteket.shop/#]rea apotek[/url] retinol apotek
ScottFup
16 Jul 25 at 5:52 pm
Medication information leaflet. Brand names.
can you get generic prednisolone without rx
All about drugs. Get information here.
can you get generic prednisolone without rx
16 Jul 25 at 5:55 pm
1win official site [url=https://1win3047.com]https://1win3047.com[/url]
1win_ncMa
16 Jul 25 at 5:59 pm
Оформиление дипломов ВУЗов по всей Украине — с печатями, подписями, приложением и возможностью архивной записи (по запросу).
Документ максимально приближен к оригиналу и проходит визуальную проверку.
Мы даем гарантию, что в случае проверки документа, подозрений не возникнет.
– Конфиденциально
– Доставка 3–7 дней
– Любая специальность
Уже более 3208 клиентов воспользовались услугой — теперь ваша очередь.
[url=http://diplomykupit6.ru/]Обращайтесь[/url] — ответим быстро, без лишних формальностей.
Kennethfiz
16 Jul 25 at 6:00 pm
Продажи KPI Используйте KPI для измерения успеха маркетинговых усилий. Выберите наиболее важные показатели, такие как трафик, конверсия, ROI и удержание клиентов. Отслеживайте прогресс и адаптируйте стратегию.
BrandonSmeag
16 Jul 25 at 6:03 pm
You actually make it seem so easy with your presentation but I find this matter to be actually something that I think I would never understand.
It seems too complicated and extremely broad for
me. I am looking forward for your next post,
I’ll try to get the hang of it!
long distance moving companies
16 Jul 25 at 6:05 pm
Проблемы с алкоголем или наркотиками могут застать врасплох и привести к серьезным последствиям для организма, психического состояния и жизни пациента. Самостоятельные попытки выйти из запоя или преодолеть абстинентный синдром без медицинской поддержки редко оказываются эффективными и могут представлять реальную опасность для здоровья. Именно в таких ситуациях клиника «АльфаНаркология» предлагает услугу вызова нарколога на дом в Санкт-Петербурге и Ленинградской области. Наши специалисты оперативно реагируют на обращение, оказывают квалифицированную помощь и обеспечивают полную конфиденциальность лечения.
Исследовать вопрос подробнее – [url=https://narcolog-na-dom-sankt-peterburg000.ru/]нарколог на дом срочно[/url]
Allensow
16 Jul 25 at 6:07 pm
По окончании курса детоксикации нарколог дает пациенту и его близким подробные рекомендации, помогающие быстрее восстановить здоровье и предотвратить повторные случаи запоев.
Получить дополнительную информацию – [url=https://vyvod-iz-zapoya-novosibirsk0.ru/]вывод из запоя круглосуточно в новосибирске[/url]
Jamestak
16 Jul 25 at 6:10 pm
Второй паспорт Гражданство Швейцарии Станьте частью стабильной и процветающей Швейцарии, получив швейцарское гражданство. Узнайте о сложном, но возможном процессе натурализации. Швейцария – это ваш символ надежности и высокого уровня жизни!
DavidTwini
16 Jul 25 at 6:13 pm
мелбет ком регистрация [url=https://melbet3001.com]https://melbet3001.com[/url]
melbet_cfkn
16 Jul 25 at 6:13 pm
1win original [url=www.1win3048.com]www.1win3048.com[/url]
1win_haMi
16 Jul 25 at 6:13 pm
заказать интернет магазин
Alvinlar
16 Jul 25 at 6:22 pm
С момента основания клиники мы делаем ставку на сочетание передовых медицинских протоколов и внимания к каждому пациенту. Наши наркологи регулярно проходят обучение на базе ведущих российских и европейских центров, что позволяет внедрять в практику новые аппараты для аппаратной детоксикации, в том числе плазмаферез и молекулярное диализирование. Психологи и психотерапевты клиники работают по стандартам когнитивно-поведенческой терапии и мотивационного интервьюирования, а наши реабилитационные курсы аккредитованы в Международной ассоциации специалистов по алкоголизму и наркомании.
Получить дополнительную информацию – [url=https://narkologicheskaya-klinika-zhukovskij4.ru/]www.domen.ru[/url]
Albertmam
16 Jul 25 at 6:23 pm
прогноз на спорт [url=http://www.prognozy-na-sport-1.ru]прогноз на спорт[/url] .
prognozi na sport_kmol
16 Jul 25 at 6:25 pm
сколько стоит сайт интернет магазина под ключ
Alvinlar
16 Jul 25 at 6:26 pm
beste online apotheek: online recept – online medicijnen bestellen zonder recept
Kennethrip
16 Jul 25 at 6:28 pm
https://snabbapoteket.com/# stora kondomer
MichaelDeeli
16 Jul 25 at 6:28 pm
Оформиление дипломов ВУЗов по всей Украине — с печатями, подписями, приложением и возможностью архивной записи (по запросу).
Документ максимально приближен к оригиналу и проходит визуальную проверку.
Мы даем гарантию, что в случае проверки документа, подозрений не возникнет.
– Конфиденциально
– Доставка 3–7 дней
– Любая специальность
Уже более 1405 клиентов воспользовались услугой — теперь ваша очередь.
[url=http://diplomykupit7.ru/]Купить диплом вуза[/url] — ответим быстро, без лишних формальностей.
Patrickbadly
16 Jul 25 at 6:29 pm
Игнорирование этих симптомов или попытки самолечения могут привести к серьезным осложнениям. Своевременная установка капельницы на дому позволяет быстро улучшить состояние пациента и минимизировать последствия запоя.
Углубиться в тему – [url=https://kapelnica-ot-zapoya-nizhniy-novgorod0.ru/]kapelnicza-ot-zapoya-czena nizhnij novgorod[/url]
MelvinExisy
16 Jul 25 at 6:32 pm
Пациенту устанавливают катетер в вену на руке или предплечье, используя лёгкий местный анестетик для минимизации дискомфорта. Затем подключают автоматизированную помпу, обеспечивающую равномерную подачу раствора в течение 3–6 часов.
Детальнее – https://kapelnica-ot-zapoya-voronezh2.ru/vyezd-na-dom-kapelnicza-ot-zapoya-v-voronezhe
Manueltroky
16 Jul 25 at 6:33 pm
Поскольку запой – это не только физическое, но и психологическое испытание, своевременная помощь нарколога является ключевым фактором для предотвращения серьезных осложнений и сохранения жизни пациента. Чем раньше начнется лечение, тем больше шанс на успешное восстановление и предотвращение повторных эпизодов.
Получить дополнительную информацию – [url=https://narcolog-na-dom-krasnoyarsk0.ru/]narkolog na dom krasnojarsk[/url]
BrianSip
16 Jul 25 at 6:35 pm
Bristol ulster university magee campus
open days showcase top-tier facilities and academic programs.
ulster university magee campus
16 Jul 25 at 6:41 pm
прогнозы ставки на спорт сайт [url=https://stavki-na-sport-prognozy.ru/]stavki-na-sport-prognozy.ru[/url] .
stavki na sport prognozi _bgOn
16 Jul 25 at 6:41 pm
доставка воды водовозом [url=dostavka-tehnicheskoi-vodi.ru]dostavka-tehnicheskoi-vodi.ru[/url] .
dostavka tehnicheskoi vodi_ddoa
16 Jul 25 at 6:42 pm
сайт с прогнозами на спорт [url=http://www.stavki-na-sport-prognozy.ru]http://www.stavki-na-sport-prognozy.ru[/url] .
stavki na sport prognozi _inOn
16 Jul 25 at 6:42 pm
привозная вода цена за куб [url=http://dostavka-tehnicheskoi-vodi.ru/]http://dostavka-tehnicheskoi-vodi.ru/[/url] .
dostavka tehnicheskoi vodi_jboa
16 Jul 25 at 6:43 pm
1win connexion [url=https://1win3048.com/]1win connexion[/url]
1win_otMi
16 Jul 25 at 6:48 pm
В течение процедуры пациент находится под непрерывным наблюдением: внутривенные капельницы с регидратационными растворами, витаминно-минеральными комплексами и гепатопротекторами обеспечивают восстановление функций печени, нормализацию обменных процессов и поддержку работы сердечно-сосудистой системы. При необходимости к лечению привлекаются узкопрофильные врачи — кардиолог, невролог или терапевт — что делает процесс максимально комплексным. По завершении выведения из запоя врач предоставляет подробный план поддерживающей терапии с рекомендациями по питанию, питьевому режиму и графику повторных консультаций.
Исследовать вопрос подробнее – [url=https://vyvod-iz-zapoya-reutov4.ru/]vyvod iz zapoya[/url]
Josephses
16 Jul 25 at 6:50 pm
Миссия нашей клиники заключается в оказании высококачественной помощи людям, страдающим от зависимостей. Мы стремимся создать безопасное и поддерживающее пространство для лечения, где каждый пациент получает необходимую поддержку и понимание. Наша задача — не только помочь избавиться от зависимости, но и вернуть полноценную жизнедеятельность человека, восстановив его социальные связи и жизненные ориентиры.
Получить больше информации – [url=https://kapelnica-ot-zapoya-irkutsk2.ru/]вызвать капельницу от запоя на дому иркутск[/url]
Herbertcop
16 Jul 25 at 6:52 pm
http://tryggmed.com/# herpes apotek
MichaelDeeli
16 Jul 25 at 6:55 pm
apotek självtest covid-19 [url=http://snabbapoteket.com/#]online pharmacy[/url] aminosyror lista
ScottFup
16 Jul 25 at 6:57 pm
создание интернет магазин цена
Alvinlar
16 Jul 25 at 6:57 pm