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!
Minotaurus coin’s ecosystem fun-focused. ICO’s legal green light. DAO votes exciting.
mtaur coin
WilliamPargy
22 Oct 25 at 12:27 am
seo продвижение россия [url=https://reiting-kompanii-po-prodvizheniyu-sajtov.ru/]seo продвижение россия[/url] .
agentstvo poiskovogo prodvijeniya_gmKt
22 Oct 25 at 12:27 am
купить диплом техникума до 1996 года [url=https://frei-diplom9.ru]купить диплом техникума до 1996 года[/url] .
Diplomi_ngea
22 Oct 25 at 12:28 am
Das Spray ist praktisch und effektiv. Meine Gelenke danken es mir
täglich.
5 Mythen über Gelenkschmerzen
5 Mythen über Gelenkschmerzen
22 Oct 25 at 12:29 am
seo продвижение рейтинг компаний [url=www.luchshie-digital-agencstva.ru/]www.luchshie-digital-agencstva.ru/[/url] .
lychshie digital agentstva_rfoi
22 Oct 25 at 12:30 am
лучший seo специалист [url=https://top-10-seo-prodvizhenie.ru]лучший seo специалист[/url] .
top 10 seo prodvijenie_oxKa
22 Oct 25 at 12:30 am
I enjoy, result in I discovered just what I was having a look for. You have ended my 4 day lengthy hunt! God Bless you man. Have a great day. Bye
easystaffingmd.com
IsmaelNek
22 Oct 25 at 12:30 am
сео компании [url=http://www.reiting-seo-agentstv.ru]сео компании[/url] .
reiting seo agentstv_xpsa
22 Oct 25 at 12:32 am
https://community.cisco.com/t5/user/viewprofilepage/user-id/1916884
Superar una prueba de orina puede ser estresante. Por eso, se desarrollo una alternativa confiable con respaldo internacional.
Su formula unica combina nutrientes esenciales, lo que estimula tu organismo y disimula temporalmente los marcadores de THC. El resultado: una orina con parametros normales, lista para pasar cualquier control.
Lo mas notable es su accion rapida en menos de 2 horas. A diferencia de otros productos, no promete resultados permanentes, sino una estrategia de emergencia que te respalda en situaciones criticas.
Estos fórmulas están diseñados para ayudar a los consumidores a limpiar su cuerpo de residuos no deseadas, especialmente esas relacionadas con el ingesta de cannabis u otras drogas.
Un buen detox para examen de fluido debe proporcionar resultados rápidos y visibles, en gran cuando el tiempo para limpiarse es limitado. En el mercado actual, hay muchas opciones, pero no todas prometen un proceso seguro o efectivo.
Qué funciona un producto detox? En términos claros, estos suplementos funcionan acelerando la depuración de metabolitos y componentes a través de la orina, reduciendo su concentración hasta quedar por debajo del umbral de detección de los tests. Algunos funcionan en cuestión de horas y su efecto puede durar entre 4 a cinco horas.
Es fundamental combinar estos productos con correcta hidratación. Beber al menos dos litros de agua por jornada antes y después del ingesta del detox puede mejorar los resultados. Además, se aconseja evitar alimentos grasos y bebidas ácidas durante el proceso de preparación.
Los mejores productos de limpieza para orina incluyen ingredientes como extractos de plantas, vitaminas del grupo B y minerales que favorecen el funcionamiento de los riñones y la función hepática. Entre las marcas más populares, se encuentran aquellas que tienen certificaciones sanitarias y estudios de resultado.
Para usuarios frecuentes de THC, 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 eficacia del producto. Por eso, combinar la disciplina con el uso correcto del detox es clave.
Un error común es creer que todos los detox actúan igual. Existen diferencias en formulación, sabor, método de toma y duración del efecto. Algunos vienen en formato líquido, otros en cápsulas, y varios combinan ambos.
Además, hay productos que incluyen fases de preparación o preparación previa al día del examen. Estos programas suelen instruir abstinencia, buena alimentación y descanso previo.
Por último, es importante recalcar que todo detox garantiza 100% de éxito. Siempre hay variables biológicas como metabolismo, nivel de consumo, y tipo de examen. Por ello, es vital seguir todas instrucciones del fabricante y no relajarse.
Miles de estudiantes ya han validado su seguridad. Testimonios reales mencionan paquetes 100% confidenciales.
Si no deseas dejar nada al azar, esta formula te ofrece seguridad.
JuniorShido
22 Oct 25 at 12:32 am
https://www.zazzle.com/mbr/238659984375374626
lmitavw
22 Oct 25 at 12:33 am
рейтинг digital seo агентств [url=http://reiting-seo-kompanii.ru/]http://reiting-seo-kompanii.ru/[/url] .
reiting seo kompanii_sbsn
22 Oct 25 at 12:34 am
купить вкладыш в диплом техникума [url=www.frei-diplom10.ru]купить вкладыш в диплом техникума[/url] .
Diplomi_heEa
22 Oct 25 at 12:34 am
продвижение сайтов в топ 10 [url=http://reiting-kompanii-po-prodvizheniyu-sajtov.ru]продвижение сайтов в топ 10[/url] .
agentstvo poiskovogo prodvijeniya_elKt
22 Oct 25 at 12:36 am
seo оптимизация сайта москва [url=https://reiting-seo-agentstv-moskvy.ru/]reiting-seo-agentstv-moskvy.ru[/url] .
reiting seo agentstv moskvi_ymMl
22 Oct 25 at 12:36 am
seo продвижение сайтов москва [url=www.reiting-seo-agentstv-moskvy.ru]www.reiting-seo-agentstv-moskvy.ru[/url] .
reiting seo agentstv moskvi_ztMl
22 Oct 25 at 12:38 am
net seo [url=https://reiting-runeta-seo.ru/]https://reiting-runeta-seo.ru/[/url] .
reiting ryneta seo_czma
22 Oct 25 at 12:39 am
купить диплом в москве [url=http://www.rudik-diplom7.ru]купить диплом в москве[/url] .
Diplomi_mqPl
22 Oct 25 at 12:39 am
top rated seo [url=top-10-seo-prodvizhenie.ru]top rated seo[/url] .
top 10 seo prodvijenie_wxKa
22 Oct 25 at 12:39 am
Blue Peak Meds: Viagra generic price comparison – BluePeakMeds
WilliamUnjup
22 Oct 25 at 12:40 am
agency seo [url=https://www.reiting-kompanii-po-prodvizheniyu-sajtov.ru]agency seo[/url] .
agentstvo poiskovogo prodvijeniya_mwKt
22 Oct 25 at 12:41 am
Вывод из запоя в Воронеже проходит анонимно, с круглосуточной поддержкой специалистов.
Подробнее – https://vyvod-iz-zapoya-v-stacionare-voronezh24.ru
Donaldjange
22 Oct 25 at 12:41 am
1xBet бонус код получите дополнительные преимущества при создании аккаунта на официальном сайте
Aaronawads
22 Oct 25 at 12:43 am
becreativeeveryday – It’s refreshing to find a creative site that isn’t full of pressure or perfection.
Marian Elsey
22 Oct 25 at 12:43 am
Заказать Хавал – только у нас вы найдете разные комплектации. Быстрей всего сделать заказ на модели хавал 2025 можно только у нас!
[url=https://havalpromsk11.ru]авто haval цена[/url]
салон хавал в москве – [url=http://havalpromsk11.ru]http://havalpromsk11.ru/[/url]
Jonatotoigo
22 Oct 25 at 12:45 am
keepgrowingwithus – The content is motivating and gives me fresh ideas to grow each day.
Cary Alken
22 Oct 25 at 12:45 am
топ сео компаний [url=http://seo-prodvizhenie-reiting.ru/]http://seo-prodvizhenie-reiting.ru/[/url] .
seo prodvijenie reiting_diEa
22 Oct 25 at 12:45 am
seo оптимизация агентство [url=https://reiting-seo-kompanii.ru/]reiting-seo-kompanii.ru[/url] .
reiting seo kompanii_posn
22 Oct 25 at 12:46 am
Marvelous, what a web site it is! This web site provides valuable facts
to us, keep it up.
Blue Peaks Roofing
22 Oct 25 at 12:47 am
findyourinnerdrive – I bookmarked a few articles because they resonated with my current goals.
Kattie Rainbolt
22 Oct 25 at 12:47 am
licensed online pharmacy UK [url=http://britmedsuk.com/#]Sildenafil 50mg[/url] NHS Viagra cost alternatives
CharlesNeono
22 Oct 25 at 12:48 am
seo продвижение сайтов в москве [url=https://reiting-seo-agentstv-moskvy.ru/]reiting-seo-agentstv-moskvy.ru[/url] .
reiting seo agentstv moskvi_kjMl
22 Oct 25 at 12:48 am
1xBet бонус при регистрации подробное описание приветственных бонусов и условий их получения
Aaronawads
22 Oct 25 at 12:50 am
Если домашние методы не помогают, вывод из запоя в стационаре в Самаре — это безопасный выбор с профессиональной детоксикацией.
Получить больше информации – [url=https://vyvod-iz-zapoya-v-stacionare-samara25.ru/]нарколог вывод из запоя в стационаре в самаре[/url]
JamesNic
22 Oct 25 at 12:51 am
сео интернет [url=http://reiting-runeta-seo.ru/]сео интернет[/url] .
reiting ryneta seo_rbma
22 Oct 25 at 12:51 am
learnandimproveeveryday – The tone feels personal, like reading advice from someone who’s been there too.
Jaye Pasquarello
22 Oct 25 at 12:52 am
лучшие seo агентства [url=http://www.luchshie-digital-agencstva.ru]лучшие seo агентства[/url] .
lychshie digital agentstva_xxoi
22 Oct 25 at 12:52 am
Can I just say what a comfort to uncover a person that actually knows what they’re discussing on the
net. You actually understand how to bring an issue to
light and make it important. More people really need to check this
out and understand this side of the story. It’s surprising you are
not more popular given that you surely possess the gift.
wedding car for rent
22 Oct 25 at 12:53 am
staymotivatedandfocused – The images and examples here helped bring the ideas to life for me.
Robert Kenderdine
22 Oct 25 at 12:53 am
Viagra online UK: Brit Meds Uk – ED medication online UK
WilliamUnjup
22 Oct 25 at 12:54 am
агентство продвижения сайтов [url=http://reiting-kompanii-po-prodvizheniyu-sajtov.ru/]агентство продвижения сайтов[/url] .
agentstvo poiskovogo prodvijeniya_siKt
22 Oct 25 at 12:56 am
рейтинг агентств интернет маркетинга [url=https://luchshie-digital-agencstva.ru]https://luchshie-digital-agencstva.ru[/url] .
lychshie digital agentstva_dmoi
22 Oct 25 at 12:56 am
топ seo компаний [url=http://top-10-seo-prodvizhenie.ru]топ seo компаний[/url] .
top 10 seo prodvijenie_ieKa
22 Oct 25 at 12:57 am
Виртуальная реальность — шаг в будущее кракен даркнет маркет kraken актуальные ссылки кракен ссылка kraken kraken официальные ссылки
RichardPep
22 Oct 25 at 12:57 am
рейтинг компаний по продвижению сайтов [url=http://www.reiting-seo-kompanii.ru]рейтинг компаний по продвижению сайтов[/url] .
reiting seo kompanii_kfsn
22 Oct 25 at 12:57 am
goldnexus – Feels like it might be a brand-new project or under development currently.
Waneta Buntz
22 Oct 25 at 12:57 am
Alas, composed pom рі pі hor, reputable primary teaches cooking,
sparking food entrepreneurship professions.
Guardians, dread missing ⅼinks hor, certain reputable schools associate
tⲟ elite secs for seamless routes.
Wah, math іs the base block for primary schooling, aiding kids
fօr geometric reasoning for architecture careers.
Αvoid play play lah, pair ɑ good primary school pluѕ arithmetic superiority fߋr enmsure elevated PSLE marks аs
welⅼ as seamless shifts.
Folks, fear tһe disparity hor, mathematics base гemains essential dսrіng primary school іn comprehending data,
essential in modern tech-driven market.
Guardians, fear tһe disparity hor, math base remains vital at primary
school іn grasping data, vital ѡithin modern online market.
Wah, arithmetic serves ɑs the base stone of primary learning, assisting children ᴡith dimensional analysis fοr building careers.
Sanctuary Primary School ρrovides an inspiring space tһat encourages creativity ɑnd achievement.
Caring educators һelp support well-rounded individuals.
Greenwood Primary School promotes outdoor learning ɑnd holistic development.
The school motivates expedition and accomplishment.
Moms ɑnd dads νalue іts nature-focused approach.
Ⴝtߋⲣ bʏ my homepаge … Kaizenare math tuition
Kaizenare math tuition
22 Oct 25 at 12:58 am
You could definitely see your skills in the article you write.
The arena hopes for even more passionate writers such as
you who are not afraid to mention how they believe.
All the time follow your heart.
şehir rehberi
22 Oct 25 at 12:58 am
Hi there mates, fastidious piece of writing and fastidious urging commented at
this place, I am actually enjoying by these.
TrevaluxPro
22 Oct 25 at 12:58 am
This is the perfect site for anybody who hopes to find out about this topic.
You understand a whole lot its almost tough to argue with you
(not that I personally will need to…HaHa). You certainly put a brand new spin on a subject that
has been discussed for years. Excellent stuff, just great!
kush casino официальный сайт зеркало
22 Oct 25 at 12:58 am
Alas, well-қnown institutions possess support assistance, leading children via anxiety fⲟr
superior mental ԝell-being and studies.
Aiyo, eh parents, tߋp institutions highlight fitness аnd health, building endurance fⲟr enduring success.
Ⅾo not mess ɑгound lah, combine a good primary school ԝith mathematics superiority
fοr ensure һigh PSLE scores аѕ well aѕ smooth shifts.
Parents, worry about tһe disparity hor, math foundation іѕ essential during primary school f᧐r comprehending figures, essential ѡithin modern online economy.
Wah, math serves ɑs thе foundation stone оf
primary learning, assisting youngsters ѡith geometric analysis tߋ building careers.
Goodness, no matter whether establishment is fancy, mathematics serves аs the critical topic in cultivatds assurance ԝith numbers.
Ꭰon’t play play lah, link а reputable primary school ѡith
arithmetic excellence іn order to assure superior PSLE scores аnd smooth cһanges.
Wellington Primary School ᧐ffers ɑ supporting environment promoting scholastic quality.
Τhе school influences trainees tһrough caring education.
Greenridge Primary School սses a nurturing environment for y᧐ung learners.
Ꮃith engaging activities, іt constructs ѕelf-confidence and understanding.
Іt’s excellent for encouraging community education.
Also visit my web-site – Queenstown Secondary School
Queenstown Secondary School
22 Oct 25 at 1:00 am