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://start.me/w/v9zARM
Pasar una prueba preocupacional puede ser un momento critico. Por eso, existe una formula avanzada probada en laboratorios.
Su composicion potente combina creatina, lo que prepara tu organismo y enmascara temporalmente los marcadores de sustancias. El resultado: una orina con parametros normales, lista para ser presentada.
Lo mas notable es su capacidad inmediata de respuesta. A diferencia de otros productos, no promete resultados permanentes, sino una herramienta puntual que te respalda en situaciones criticas.
Estos productos están diseñados para colaborar a los consumidores a depurar su cuerpo de componentes no deseadas, especialmente aquellas relacionadas con el ingesta de cannabis u otras sustancias.
El buen detox para examen de orina debe brindar resultados rápidos y confiables, en especial cuando el tiempo para limpiarse es limitado. En el mercado actual, hay muchas opciones, pero no todas prometen un proceso seguro o fiable.
Qué funciona un producto detox? En términos claros, estos suplementos operan acelerando la depuración de metabolitos y residuos a través de la orina, reduciendo su nivel hasta quedar por debajo del umbral de detección de los tests. Algunos funcionan en cuestión de horas y su impacto puede durar entre 4 a seis horas.
Resulta fundamental combinar estos productos con correcta hidratación. Beber al menos par litros de agua al día antes y después del uso del detox puede mejorar los beneficios. Además, se sugiere evitar alimentos grasos y bebidas procesadas durante el proceso de preparación.
Los mejores productos de detox para orina incluyen ingredientes como extractos de plantas, vitaminas del grupo B y minerales que favorecen el funcionamiento de los sistemas y la función hepática. Entre las marcas más destacadas, se encuentran aquellas que tienen certificaciones sanitarias y estudios de resultado.
Para usuarios frecuentes de marihuana, se recomienda usar detoxes con ventanas de acción largas o iniciar una preparación previa. Mientras más prolongada sea la abstinencia, mayor será la efectividad del producto. Por eso, combinar la planificación con el uso correcto del producto es clave.
Un error común es suponer que todos los detox actúan idéntico. Existen diferencias en dosis, sabor, método de ingesta y duración del impacto. Algunos vienen en presentación líquido, otros en cápsulas, y varios combinan ambos.
Además, hay productos que incluyen fases de preparación o limpieza previa al día del examen. Estos programas suelen instruir abstinencia, buena alimentación y descanso recomendado.
Por último, es importante recalcar que ningún detox garantiza 100% de éxito. Siempre hay variables personales como metabolismo, historial de consumo, y tipo de examen. Por ello, es vital seguir todas instrucciones del fabricante y no relajarse.
Miles de postulantes ya han validado su rapidez. Testimonios reales mencionan paquetes 100% confidenciales.
Si no deseas dejar nada al azar, esta formula te ofrece respaldo.
JuniorShido
20 Oct 25 at 12:16 am
A motivating discussion is definitely worth comment.
I do believe that you should publish more on this subject matter, it might not be
a taboo matter but usually people do not speak about such issues.
To the next! All the best!!
Solve reCAPTCHAs
20 Oct 25 at 12:16 am
If you want to take a good deal from this post then you
have to apply such strategies to your won weblog.
유흥알바
20 Oct 25 at 12:18 am
купить диплом в хабаровске [url=rudik-diplom9.ru]rudik-diplom9.ru[/url] .
Diplomi_fdei
20 Oct 25 at 12:19 am
медоборудование [url=http://medtehnika-msk.ru/]медоборудование[/url] .
oborydovanie medicinskoe_gupa
20 Oct 25 at 12:19 am
To maximize online security and anonymity, pair a reliable antidetect solution with high-quality proxies. Choose an antidetect browser that provides seamless integration for all proxy types (SOCKS5, HTTP) to mask your IP address effectively.
DouglasJasse
20 Oct 25 at 12:20 am
Just grabbed some $MTAUR coins during the presale—feels like getting in on the ground floor of something huge. The audited smart contracts give me peace of mind, unlike sketchier projects. Can’t wait for the game beta to test those power-ups.
mtaur coin
WilliamPargy
20 Oct 25 at 12:20 am
В Краснодаре клиника «Детокс» предоставляет услугу вызова нарколога на дом. Специалисты приедут к вам в течение 1–2 часов, проведут осмотр и назначат необходимое лечение. Все процедуры проводятся анонимно и с соблюдением конфиденциальности.
Детальнее – [url=https://narkolog-na-dom-krasnodar26.ru/]врач нарколог выезд на дом краснодар[/url]
DanielCaupe
20 Oct 25 at 12:20 am
купить диплом техникума в спб [url=http://www.frei-diplom9.ru]купить диплом техникума в спб[/url] .
Diplomi_yfea
20 Oct 25 at 12:21 am
купить диплом в костроме [url=http://rudik-diplom6.ru/]http://rudik-diplom6.ru/[/url] .
Diplomi_eyKr
20 Oct 25 at 12:23 am
вывод из запоя в москве недорого [url=https://vyvod-iz-zapoya-9.ru/]https://vyvod-iz-zapoya-9.ru/[/url] .
vivod iz zapoya_rwEl
20 Oct 25 at 12:24 am
Before committing, read detailed antidetect browser reviews. User testimonials and expert analysis provide insights into features like profile isolation, proxy support, and stability for your workflow.
DouglasJasse
20 Oct 25 at 12:24 am
Thank you, I have recently been looking for info approximately
this subject for a long time and yours is the greatest I’ve discovered
so far. But, what about the conclusion? Are you certain about the source?
data sydney prize 2025
20 Oct 25 at 12:24 am
1вин [url=http://1win5510.ru/]http://1win5510.ru/[/url]
1win_uz_mqsi
20 Oct 25 at 12:24 am
Капельница от запоя на дому в Нижнем Новгороде — удобное решение для тех, кто не может посетить клинику. Наши специалисты приедут к вам домой и проведут необходимую процедуру.
Получить дополнительную информацию – [url=https://vyvod-iz-zapoya-nizhnij-novgorod12.ru/]анонимный вывод из запоя нижний новгород[/url]
Miltondiolo
20 Oct 25 at 12:25 am
Клиника «Похмельная служба» в Нижнем Новгороде предлагает капельницу от запоя с выездом на дом. Наши специалисты обеспечат вам комфортное и безопасное лечение в привычной обстановке.
Получить дополнительную информацию – [url=https://vyvod-iz-zapoya-nizhnij-novgorod11.ru/]врач вывод из запоя[/url]
TerrellOwelf
20 Oct 25 at 12:27 am
I’m not sure why but this web site is loading very slow for me.
Is anyone else having this issue or is it a problem on my end?
I’ll check back later and see if the problem still exists.
alston antony
20 Oct 25 at 12:28 am
купить диплом в арзамасе [url=https://rudik-diplom7.ru]купить диплом в арзамасе[/url] .
Diplomi_taPl
20 Oct 25 at 12:28 am
монтаж гидроизоляции [url=https://ustroystvo-gidroizolyacii.ru/]ustroystvo-gidroizolyacii.ru[/url] .
ystroistvo gidroizolyacii_lsea
20 Oct 25 at 12:30 am
1win bonus kod uz [url=https://www.1win5510.ru]1win bonus kod uz[/url]
1win_uz_rusi
20 Oct 25 at 12:31 am
диплом техникума купить в челябинске [url=http://frei-diplom9.ru]диплом техникума купить в челябинске[/url] .
Diplomi_tlea
20 Oct 25 at 12:31 am
1win sportga tikish [url=1win5509.ru]1win5509.ru[/url]
1win_uz_ilKt
20 Oct 25 at 12:35 am
Выездная наркологическая помощь в Нижнем Новгороде — капельница от запоя с выездом на дом. Мы обеспечиваем быстрое и качественное лечение без необходимости посещения клиники.
Углубиться в тему – [url=https://vyvod-iz-zapoya-nizhnij-novgorod12.ru/]нарколог вывод из запоя в нижний новгороде[/url]
Miltondiolo
20 Oct 25 at 12:35 am
где купить диплом образование [url=www.rudik-diplom9.ru]где купить диплом образование[/url] .
Diplomi_vrei
20 Oct 25 at 12:35 am
Нарколог прибывает в назначенное время, проводит замеры артериального давления, пульса, сатурации кислорода и температуры. Выполняется экспресс-анализ на содержание алкоголя в крови и оценка водно-электролитного баланса.
Разобраться лучше – [url=https://narkologicheskaya-klinika-rostov13.ru/]анонимная наркологическая клиника ростов-на-дону[/url]
JosephNoirl
20 Oct 25 at 12:36 am
1вин рабочее зеркало [url=1win5509.ru]1win5509.ru[/url]
1win_uz_djKt
20 Oct 25 at 12:37 am
Стационар «Частного Медика?24» помогает безопасно и быстро восстановиться после длительного запоя.
Углубиться в тему – [url=https://vyvod-iz-zapoya-v-stacionare-voronezh23.ru/]стационар вывод из запоя в воронеже[/url]
Anthonyvom
20 Oct 25 at 12:37 am
купить диплом в новотроицке [url=rudik-diplom14.ru]купить диплом в новотроицке[/url] .
Diplomi_jrea
20 Oct 25 at 12:38 am
прерывание запоя москва [url=http://www.vyvod-iz-zapoya-9.ru]http://www.vyvod-iz-zapoya-9.ru[/url] .
vivod iz zapoya_gvEl
20 Oct 25 at 12:41 am
мелбет [url=https://melbetbonusy.ru/]мелбет[/url] .
melbet_pfOi
20 Oct 25 at 12:41 am
Hmm it looks like your blog ate my first comment (it was extremely long)
so I guess I’ll just sum it up what I submitted and say, I’m
thoroughly enjoying your blog. I as well am an aspiring blog writer but I’m still new to everything.
Do you have any tips for first-time blog writers?
I’d certainly appreciate it.
BETFLIX45
20 Oct 25 at 12:41 am
купить аттестаты за 11 [url=rudik-diplom7.ru]купить аттестаты за 11[/url] .
Diplomi_plPl
20 Oct 25 at 12:42 am
аппараты медицинские [url=medtehnika-msk.ru]аппараты медицинские[/url] .
oborydovanie medicinskoe_jqpa
20 Oct 25 at 12:43 am
Acho simplesmente alucinante RioPlay Casino, tem uma vibe de jogo tao animada quanto um desfile na Sapucai. Tem uma avalanche de jogos de cassino irados, incluindo jogos de mesa de cassino com gingado. Os agentes do cassino sao rapidos como um passista, garantindo suporte de cassino direto e sem perder o ritmo. Os pagamentos do cassino sao lisos e blindados, de vez em quando mais recompensas no cassino seriam um diferencial brabo. No geral, RioPlay Casino oferece uma experiencia de cassino que e puro axe para quem curte apostar com gingado no cassino! Alem disso a navegacao do cassino e facil como um passo de carnaval, adiciona um toque de axe ao cassino.
rioplay games|
wildpineapplegator3zef
20 Oct 25 at 12:44 am
Корзины цветов — это камерная роскошь, которая уместна дома, в офисе и на мероприятиях: готовая композиция не требует вазы и сразу создаёт атмосферу. В каталоге «Флорион» — десятки решений от изящных до масштабных, с гибкими ценами и фильтрами по цветам и поводам. Оцените подбор на https://www.florion.ru/catalog/korziny-cvetov и выбирайте формат — романтичный, праздничный или строгий. Свежесть, аккуратная посадка в оазис и оперативная доставка по Москве гарантированы.
gefojbef
20 Oct 25 at 12:44 am
устройство гидроизоляции [url=http://ustroystvo-gidroizolyacii.ru/]http://ustroystvo-gidroizolyacii.ru/[/url] .
ystroistvo gidroizolyacii_goea
20 Oct 25 at 12:46 am
News.net.uz — компактная карта событий Узбекистана: сводки, экономика, общество, спорт и культура в одном потоке. Редакция оперативно агрегирует сообщения ведомств и местных медиа, отмечая ключевые факты и контекст. Удобно читать с телефона: лаконичные заголовки ведут к развернутым материалам, а блоки «Интересное» и «Курсы валют» экономят время. Заходите на https://news.net.uz/ — следите за важными решениями, городскими новостями и аналитикой без перегруза и рекламы.
bazalAxoft
20 Oct 25 at 12:47 am
купить диплом товароведа [url=http://rudik-diplom6.ru]купить диплом товароведа[/url] .
Diplomi_kkKr
20 Oct 25 at 12:48 am
Excited for Minotaurus presale’s deals. $MTAUR’s zones special. Engagement high.
minotaurus presale
WilliamPargy
20 Oct 25 at 12:51 am
I was wondering if you ever thought of changing the layout of your site?
Its ery well written; I love what youve ggot to say.
But maybe you could a little more inn the way of content
soo people could connect with it better. Youve
got ann awful lot of text for only havig 1 or 2 pictures.
Maybe you could space it out better?
Visit myy homepage seo services kuala lumpur
seo services kuala lumpur
20 Oct 25 at 12:53 am
помощь алкоголику на дому [url=https://www.narkolog-na-dom-1.ru]https://www.narkolog-na-dom-1.ru[/url] .
narkolog na dom_edkt
20 Oct 25 at 12:54 am
Оно помогает поддерживать чистоту и порядок в
помещении, а также удалять грязь,
пыль и другие загрязнения.
заказать уборку в Uberu24
20 Oct 25 at 12:54 am
современное медицинское оборудование [url=https://medtehnika-msk.ru/]medtehnika-msk.ru[/url] .
oborydovanie medicinskoe_mmpa
20 Oct 25 at 12:54 am
купить диплом в дзержинске [url=https://rudik-diplom7.ru]купить диплом в дзержинске[/url] .
Diplomi_vpPl
20 Oct 25 at 12:55 am
I am sure this paragraph has touched all the internet people, its really
really nice piece of writing on building up new blog.
scooter tuning
20 Oct 25 at 12:55 am
вывод из запоя в москве недорого [url=http://vyvod-iz-zapoya-9.ru]http://vyvod-iz-zapoya-9.ru[/url] .
vivod iz zapoya_lcEl
20 Oct 25 at 12:55 am
купить бланк диплома [url=http://rudik-diplom9.ru/]купить бланк диплома[/url] .
Diplomi_tsei
20 Oct 25 at 12:57 am
Ищете помощь при зависимости — для себя или близкого? Статья «Наркологическая клиника и её услуги» раскрывает, как специализированные учреждения помогают людям справиться с зависимостью — будь то алкоголизм или другие формы. Изучить вопрос глубже – http://kremlevsk.kamrbb.ru/?x=read&razdel=9&tema=1101
Heathergak
20 Oct 25 at 1:00 am
Galera, vim dividir minhas impressoes no 4PlayBet Casino porque me impressionou bastante. A variedade de jogos e surreal: blackjack envolvente, todos sem travar. O suporte foi rapido, responderam em minutos pelo chat, algo que faz diferenca. Fiz saque em transferencia e o dinheiro entrou sem enrolacao, ponto fortissimo. Se tivesse que criticar, diria que podia ter mais promocoes semanais, mas isso nao estraga a experiencia. Resumindo, o 4PlayBet Casino vale demais a pena. Vale experimentar.
loja 4play|
neonfalcon88zef
20 Oct 25 at 1:01 am
Great blog here! Also your website loads up fast! What host are you using?
Can I get your affiliate link to your host? I wish my web site loaded
up as fast as yours lol
j88slot
20 Oct 25 at 1:01 am