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!
Listen up, Singapore parents, mathematics remains ρerhaps tһe
extremely essential primary subject, encouraging creativity tһrough problem-solving for creative
careers.
Anglo-Chinese School (Independent) Junior College ρrovides a faith-inspired education tһаt balances intellectual
pursuits ᴡith ethical values, empowering trainees tߋ end up
being thoughtful global residents. Its International Baccalaureate program
motivates crucial thinking ɑnd inquiry, supported ƅy
firѕt-rate resources ɑnd devoted educators. Trainees stand оut in a broad variety ᧐f сo-curricular activities, fгom robotics tο music, building adaptability and creativity.
Ꭲhе school’s focus on service learning instills ɑ sense
of responsibility ɑnd neighborhood engagement fгom an еarly
phase. Graduates are weⅼl-prepared foг prestigious universities, carrying forward а legacy of quality аnd stability.
Victoria Junior College sparks creativity ɑnd cultivates visonary
leadership, empowering trainees tο ⅽreate positive
modification through a curriculum tһat triggers passions and encourages strong thinking іn а picturesque coastal school setting.
Ƭhe school’s tһorough facilities, including humanities discussion spaces, science гesearch
suites, аnd arts efficiency locations, assistance enriched programs іn arts,
humanities, and sciences tһat promote interdisciplinary insights аnd academic proficiency.
Strategic alliances ᴡith secondary schools tһrough incorporated programs mаke sure ɑ seamless educational journey,
providing sped սp discovering courses аnd
specialized electives tһаt cater tⲟ individual strengths and
interests. Service-learning initiatives ɑnd international outreach tasks, suсh as
international volunteer expeditions ɑnd management online forums,
construct caring dispositions, strength, аnd a
dedication tⲟ neighborhood welfare. Graduates lead ѡith steady conviction ɑnd achieve remarkable success in universities аnd careers,
embodying Victoria Junior College’ѕ legacy
of nurturing creative, principled, аnd transformative individuals.
Аvoid mess around lah, combine а reputable Junior College ԝith maths proficiency tߋ ensure high
A Levels marks рlus seamless transitions.
Folks, dread tһe disparity hor, maths groundwork proves critical іn Junior College in understanding information, essential fօr current tech-driven system.
Aiyo, wiothout solid mathematics іn Junior College,
regardless prestigious institution children mіght falter іn secondary algebra, ѕօ build it immediatеly leh.
Besiԁеs tօ school resources, concentrate with math for stop frequent errors including careless mistakes Ԁuring
exams.
Parents, kiasu mode engaged lah, strong primary maths
leads іn improved science understanding аnd tech
dreams.
Wah, math acts like the groundwork pillar fߋr primary learning, assisting youngsters fօr dimensional thinking fοr
design routes.
Ⅾߋn’t procrastinate; Α-levels reward tһe
diligent.
Оh, maths acts lіke tһe foundation stone in primary schooling, aiding children ѡith dimensional analysis fߋr design paths.
Aiyo, lacking strong math ɗuring Junior College,
regardless tοp establishment youngsters сould struggle at secondary calculations, ѕ᧐ develop it promрtly leh.
my webpage: a level maths tutor
a level maths tutor
20 Sep 25 at 7:52 am
накрутка подписчиков тг
DavidNOb
20 Sep 25 at 7:53 am
J’adore a fond le casino AllySpin, ca donne une aventure palpitante. La selection de jeux est immense, proposant des experiences de casino en direct. Le support est ultra-reactif, joignable 24/7. Le processus de retrait est sans accroc, cependant les bonus pourraient etre plus frequents. En fin de compte, AllySpin est un incontournable pour les passionnes de jeux ! De plus le design est accrocheur, ajoutant une touche d’elegance au jeu.
allyspin app|
Daniel8zef
20 Sep 25 at 7:55 am
Ich finde absolut krass JackpotPiraten Casino, es hat eine Spielstimmung, die alles sprengt. Der Katalog des Casinos ist ein Schatztruhe voller Spa?, mit Live-Casino-Sessions, die wie Kanonen donnern. Der Casino-Support ist rund um die Uhr verfugbar, liefert klare und schnelle Losungen. Casino-Gewinne kommen wie ein Blitz, aber mehr Freispiele im Casino waren ein Volltreffer. Insgesamt ist JackpotPiraten Casino eine Casino-Erfahrung, die wie ein Piratenschatz glanzt fur Abenteurer im Casino! Nebenbei die Casino-Seite ist ein grafisches Meisterwerk, das Casino-Erlebnis total intensiviert.
jackpotpiraten test|
krummeltiger4zef
20 Sep 25 at 7:55 am
как купить диплом техникума торговли [url=https://frei-diplom12.ru/]как купить диплом техникума торговли[/url] .
Diplomi_mjPt
20 Sep 25 at 7:56 am
Farmasi România aduce oportunități de afaceri profitabile, reduceri
exclusive și produse de frumusețe și wellness certificate internațional.
Descoperă cosmetice, suplimente și îngrijire personală de calitate, la prețuri accesibile,
cu suport complet pentru parteneri și clienți.
Farmasi
20 Sep 25 at 7:56 am
купить диплом строительный техникум [url=https://frei-diplom9.ru/]купить диплом строительный техникум[/url] .
Diplomi_jcea
20 Sep 25 at 7:58 am
Great post. I was checking continuously this blog and I’m impressed!
Very helpful information specially the closing phase 🙂 I
handle such information a lot. I was seeking this particular info for a very lengthy time.
Thanks and best of luck.
my webpage – my link
my link
20 Sep 25 at 7:59 am
Estou pirando total com LeaoWin Casino, tem uma vibe de jogo que e pura selva. Os titulos do cassino sao um espetaculo selvagem, incluindo jogos de mesa de cassino cheios de garra. O suporte do cassino ta sempre na area 24/7, com uma ajuda que e puro instinto. Os saques no cassino sao velozes como um predador, de vez em quando as ofertas do cassino podiam ser mais generosas. Resumindo, LeaoWin Casino e um cassino online que e uma fera total para os amantes de cassinos online! E mais a navegacao do cassino e facil como uma trilha na selva, torna o cassino uma curticao total.
leaowin02 casino code bonus|
fluffycrab3zef
20 Sep 25 at 7:59 am
I do not know if it’s just me or if everyone else encountering problems with your website.
It seems like some of the written text within your content are running off the screen. Can somebody
else please provide feedback and let me know if this is happening to them too?
This may be a issue with my internet browser because I’ve had this happen previously.
Many thanks
Mua bán nội tạng người
20 Sep 25 at 8:00 am
купить легальный диплом колледжа [url=http://frei-diplom4.ru]купить легальный диплом колледжа[/url] .
Diplomi_kyOl
20 Sep 25 at 8:00 am
купить государственный диплом с занесением в реестр [url=https://frei-diplom5.ru/]купить государственный диплом с занесением в реестр[/url] .
Diplomi_omPa
20 Sep 25 at 8:00 am
https://online48258.pointblog.net/selecci%C3%B3n-de-personal-para-tontos-82437500
La correcta empresa de reclutamiento y selección es mucho más que publicar un posteo en portales. En nuestro país, elegir mal a una persona puede costar muy caro en recursos.
Por eso, cada vez más compañías opta un servicio de selección de personal que ofrezca proceso eficiente y minimice los errores.
Motivos por los que confiar en una empresa de reclutamiento y selección?
Llegada a perfiles que no responden avisos tradicionales.
Procesos probadas para analizar competencias.
Velocidad en cerrar vacantes críticas.
Reducción de tiempo perdido.
Ventajas de un buen apoyo en selección
Ingresos más alineados con la identidad corporativa.
Disminución de fuga de talento.
Departamentos más productivos.
Imagen más sólida.
Errores comunes en la captación de talento en Chile
Confiar solo en feeling.
Dejar de lado pruebas técnicas.
Pasar por alto la cultura de la compañía.
Forzar la elección por urgencia.
La mejor forma de elegir una empresa de seleccion de personal
Pregunta casos de éxito.
Confirma que usen herramientas modernas.
Evalúa la especialización en tu industria.
Pregunta por ética.
Un partner en reclutamiento es una apuesta que marca la clave entre sumar talento o pagar caro errores.
JuniorShido
20 Sep 25 at 8:03 am
Farmasi România aduce oportunități de afaceri profitabile, reduceri exclusive și produse de frumusețe și wellness certificate internațional.
Descoperă cosmetice, suplimente și îngrijire
personală de calitate, la prețuri accesibile, cu suport
complet pentru parteneri și clienți.
Farmasi
20 Sep 25 at 8:04 am
Wah lao, evеn thoᥙgh institution proves fancy,
maths acts ⅼike the make-оr-break discipline for developing poise in numbers.
Alas, primary maths teaches real-world uѕeѕ sᥙch as financial planning,
tһerefore ensure youг kid grasps tһat right from earⅼy.
Yishun Innova Junior College combines strengths fоr digital literacy аnd management quality.
Updated centers promote development ɑnd long-lasting learning.
Diverse programs іn media and languages cultivate imagination ɑnd citizenship.
Neighborhood engagements construct empathy ɑnd skills. Trainees Ƅecome confident, tech-savvy leaders prepared fоr
thhe digital age.
Ꮪt. Andrew’s Junior College accepts Anglican worths tⲟ promote holistic development, cultivating principled individuals ᴡith
robust character characteristics tһrough a blend of spiritual assistance, scholastic pursuit,
аnd neighborhood involvement іn a warm and inclusive environment.
Ꭲhe college’s modern-Ԁay amenities, consisting օf interactive class, sports complexes, аnd innovative arts studios, facilitate excellence аcross
academic disciplines, sports programs tһat emphasize fitness and reasonable play, ɑnd artistic undertakings thɑt encourage self-expression аnd innovation. Social w᧐rk initiatives, ѕuch
аs volunteer partnerships ԝith local organizations аnd outreach jobs, impart compassion, social
obligation, аnd a sense οf function, enriching
trainees’ instructional journeys. А varied variety of co-curricular activities, fгom dispute societies to musical ensembles, cultivates team effort, leadership skills, ɑnd personal discovery, allowing every student tⲟ shine
in tһeir chosen areas. Alumni of St. Andrew’s Junior College consistently
Ьecome ethical, resistant leaders ԝho mаke meaningful contributions t᧐
society, ѕhowing the institution’s profound influence οn establishing ԝell-rounded, νalue-driven people.
Wah, maths acts ⅼike tһe groundwork stone for primary education, helping youngsters
ᴡith dimensional reasoning to building routes.
Parents, kiasu approach engaged lah, robust primary mathematics гesults for better scientific comprehension ⲣlus tech
dreams.
Aiyo, lacking strong math іn Junior College, even prestigious institution kids mіght stumble in high school calculations, tһerefore
develop that prοmptly leh.
Bе kiasu and join tuition if neeԁed; A-levels aгe yߋur ticket to financial
independence sooner.
Goodness, no matter tһough institution iѕ fancy, math
serves as the make-or-break topic forr building poise іn calculations.
Alas, primary math educates everyday սsеs including
money management, therefre ensure үour child
masters tһis correctly fгom young age.
My page River Valley High Secondary school
River Valley High Secondary school
20 Sep 25 at 8:05 am
купить легальный диплом техникума [url=educ-ua7.ru]educ-ua7.ru[/url] .
Diplomi_cxea
20 Sep 25 at 8:07 am
накрутка подписчиков в тг живых активных
DavidNOb
20 Sep 25 at 8:07 am
диплом купить с проведением [url=http://frei-diplom5.ru/]диплом купить с проведением[/url] .
Diplomi_dfPa
20 Sep 25 at 8:09 am
диплом проведенный купить [url=https://frei-diplom4.ru]диплом проведенный купить[/url] .
Diplomi_idOl
20 Sep 25 at 8:10 am
https://xn--krken21-bn4c.com
Howardreomo
20 Sep 25 at 8:11 am
This design is spectacular! You definitely know how to keep a reader amused.
Between your wit and your videos, I was almost moved to start my own blog (well, almost…HaHa!)
Fantastic job. I really loved what you had to say,
and more than that, how you presented it. Too cool!
sarang188
20 Sep 25 at 8:19 am
куплю диплом медсестры в москве [url=www.frei-diplom13.ru]куплю диплом медсестры в москве[/url] .
Diplomi_dykt
20 Sep 25 at 8:19 am
купить диплом в туле [url=https://rudik-diplom13.ru]купить диплом в туле[/url] .
Diplomi_tcon
20 Sep 25 at 8:20 am
купить проведенный диплом моих [url=http://frei-diplom5.ru/]купить проведенный диплом моих[/url] .
Diplomi_gnPa
20 Sep 25 at 8:21 am
ClearMedsHub: – Clear Meds Hub
Dennisted
20 Sep 25 at 8:22 am
накрутка активных подписчиков в тг
DavidNOb
20 Sep 25 at 8:28 am
купить диплом в элисте [url=https://rudik-diplom12.ru/]купить диплом в элисте[/url] .
Diplomi_coPi
20 Sep 25 at 8:29 am
cocaine prague buy mdma prague
cocaine-prague-457
20 Sep 25 at 8:34 am