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!
заказать выравнивание участка
заказать выравнивание участка
18 Sep 25 at 9:26 am
https://information77394.ampblogs.com/consutloria-de-perfiles-de-cargo-63135977
La generación de perfiles de cargo es hoy un reto estratégico para pymes que buscan expandirse. Sin adecuado diseño perfiles de cargo, los flujos de contratación se transforman ineficientes y el match con los postulantes fracasa.
En Chile, donde los mercados mutan a gran velocidad, el mapeo de perfiles de cargo ya no es opcional. Es la estrategia viable de mapear qué competencias son requeridas en cada rol.
Piénsalo: sin una actualizacion perfiles de cargo, tu organización arriesga dinero reclutando mal. Los documentos de cargo que se mantienen obsoletos desmotivan tanto a líderes como a equipos.
Problemas comunes al trabajar fichas de cargo
Escribir perfiles demasiado genéricas.
Reutilizar modelos gringos que no aplican en la cultura local.
Ignorar la renovación de perfiles de cargo después de reestructuraciones.
No involucrar a los colaboradores en el diseño perfiles de cargo.
Claves para un diseño perfiles de cargo exitoso
Comenzar con el mapa de perfiles de cargo: entrevistas, focus groups y encuestas a líderes.
Alinear skills necesarias y requisitos técnicos.
Diseñar un documento claro que explique funciones y rangos de rendimiento.
Establecer la revisión de perfiles de cargo al menos cada ciclo.
Cuando los roles definidos están actualizados, tu negocio alcanza tres ganancias concretas:
Selecciones más certeros.
Trabajadores más comprometidos.
Planes de desarrollo más justos.
JuniorShido
18 Sep 25 at 9:27 am
buy drugs in prague high quality cocaine in prague
prague-drugs-562
18 Sep 25 at 9:29 am
Hello folks!
I came across a 134 awesome site that I think you should take a look at.
This site is packed with a lot of useful information that you might find valuable.
It has everything you could possibly need, so be sure to give it a visit!
[url=https://ronnielawsmusic.com/bets-on-sport/registering-on-a-sportsbook-with-quality-bonuses/]https://ronnielawsmusic.com/bets-on-sport/registering-on-a-sportsbook-with-quality-bonuses/[/url]
And do not forget, guys, that one always may in this particular article find answers to address the most the very confusing queries. The authors attempted to lay out all of the data using the most very easy-to-grasp method.
Anya134et
18 Sep 25 at 9:31 am
It’s amazing for me to have a web site, which is beneficial in support of
my know-how. thanks admin
آدرس دانشگاه فرهنگیان تربیت دبیر شهید رجایی تهران
18 Sep 25 at 9:34 am
микрозаймы онлайн [url=www.zaimy-14.ru]микрозаймы онлайн[/url] .
zaimi_kxSr
18 Sep 25 at 9:35 am
Adoro a energia de DonaldBet Casino, pulsa com uma forca de cassino digna de um mestre de cerimonias. O catalogo de jogos e um picadeiro de prazeres. com jogos adaptados para criptomoedas. O servico e confiavel como uma corda bamba. respondendo veloz como uma acrobacia. Os saques voam como um acrobata. as vezes queria mais promocoes que brilham como holofotes. No geral, DonaldBet Casino e uma explosao de adrenalina para os amantes de cassinos online! E mais a interface e fluida e brilha como um picadeiro. elevando a imersao ao nivel de um espetaculo.
donaldbet|
flickerzippyowl5zef
18 Sep 25 at 9:36 am
Публикация предлагает уникальную подборку информации, которая будет интересна как специалистам, так и широкому кругу читателей. Здесь вы найдете ответы на часто задаваемые вопросы и полезные инсайты для дальнейшего применения.
Открыть полностью – https://niigata-dream.com/post-503
MatthewSwess
18 Sep 25 at 9:37 am
cocaine in prague https://cocaine-prague-shop.com
prague-drugs-46
18 Sep 25 at 9:38 am
Dragon Money – популярное казино с быстрыми выплатами и отличным ассортиментом игр на любой вкус
drgn
Briananivy
18 Sep 25 at 9:38 am
автоматический карниз для штор [url=www.razdvizhnoj-elektrokarniz.ru/]www.razdvizhnoj-elektrokarniz.ru/[/url] .
razdvijnoi elektrokarniz_efei
18 Sep 25 at 9:39 am
займы россии [url=http://zaimy-14.ru/]http://zaimy-14.ru/[/url] .
zaimi_qjSr
18 Sep 25 at 9:40 am
Эта публикация завернет вас в вихрь увлекательного контента, сбрасывая стереотипы и открывая двери к новым идеям. Каждый абзац станет для вас открытием, полным ярких примеров и впечатляющих достижений. Подготовьтесь быть вовлеченными и удивленными каждый раз, когда продолжите читать.
Как достичь результата? – https://raghebabuhamdan.com/al-yom-al-sabee-%F0%9F%87%AA%F0%9F%87%AC
Andrewpsymn
18 Sep 25 at 9:40 am
купить диплом о высшем образовании с реестром [url=www.educ-ua11.ru]купить диплом о высшем образовании с реестром[/url] .
Diplomi_vuPi
18 Sep 25 at 9:41 am
как купить диплом с занесением в реестр [url=https://educ-ua14.ru/]как купить диплом с занесением в реестр[/url] .
Diplomi_vmkl
18 Sep 25 at 9:41 am
Hello just wanted to give you a quick heads up and let you
know a few of the pictures aren’t loading properly.
I’m not sure why but I think its a linking issue. I’ve tried it in two different
internet browsers and both show the same results.
Puro Bitline
18 Sep 25 at 9:42 am
все займы на карту [url=http://www.zaimy-14.ru]все займы на карту[/url] .
zaimi_mrSr
18 Sep 25 at 9:42 am
https://bio.site/jidoiduhoby
Timothyces
18 Sep 25 at 9:42 am
[url=https://balatonnyomda.hu/sign/pgs/promo_code_81.html]best promo code 1xbet eg[/url]
Charlesblace
18 Sep 25 at 9:43 am
электрокарниз купить в москве [url=www.razdvizhnoj-elektrokarniz.ru]www.razdvizhnoj-elektrokarniz.ru[/url] .
razdvijnoi elektrokarniz_ziei
18 Sep 25 at 9:44 am
Dragon Money – захватывающее онлайн-казино с огромным выбором игр и щедрыми бонусами https://www.ds100nezabudka.ru/
ManuelSow
18 Sep 25 at 9:44 am
I am now not certain where you are getting your info,
but great topic. I needs to spend some time finding out more or working out more.
Thanks for excellent info I was looking for this information for my mission.
33win
18 Sep 25 at 9:45 am
все займы онлайн [url=https://zaimy-15.ru]все займы онлайн[/url] .
zaimi_thpn
18 Sep 25 at 9:46 am
все займы ру [url=http://zaimy-16.ru/]http://zaimy-16.ru/[/url] .
zaimi_dbMi
18 Sep 25 at 9:47 am
Thanks for the auspicious writeup. It in truth used to be a entertainment account it.
Look complex to far delivered agreeable from you!
However, how can we keep in touch?
official website
18 Sep 25 at 9:47 am
Dragon Money – захватывающее онлайн-казино с огромным выбором игр и щедрыми бонусами
drgn
ManuelSow
18 Sep 25 at 9:48 am
Yesterday, while I was at work, my cousin stole
my apple ipad and tested to see if it can survive a twenty five foot
drop, just so she can be a youtube sensation. My iPad is now destroyed and she has 83 views.
I know this is completely off topic but I had to share it with someone!
Meteor Profit
18 Sep 25 at 9:48 am
https://www.wildberries.ru/catalog/171056105/detail.aspx
Curtissab
18 Sep 25 at 9:49 am
Je suis envoute par RollBit Casino, est un tourbillon de divertissement qui pixelise. Il y a une cascade de jeux de casino captivants. incluant des tables qui structurent comme un cube. repond comme un pixel precis. avec une aide qui cube comme un bit. Les transactions du casino sont simples comme un pixel. parfois les offres du casino pourraient etre plus genereuses. A la fin, RollBit Casino enchante avec une rhapsodie de jeux pour les explorateurs de melodies en ligne! Bonus le design du casino est une fresque visuelle numerique. ajoute une touche de rythme numerique au casino.
rollbit coin price|
whirlflameotter8zef
18 Sep 25 at 9:49 am
Since India’s independence from Britain in 1947, the status of English in India has been deeply political – entwined with questions of identity, power, and national direction.
Today, English is one of several official languages in India, spoken by about 10% of the population. Hindi is the first language for around 44% of citizens, according to the 2011 census.
[url=https://trip-scan.biz]трипскан [/url]
But in recent years, Modi’s BJP has placed particular emphasis on promoting Hindi and reducing the use of English in public life.
The prime minister almost never delivers speeches in English, preferring Hindi for national addresses such as his monthly radio program. His administration has encouraged officials to use Hindi on social media and in government correspondence – though, after criticism from non-Hindi-speaking states, clarified that this was intended mainly for the Hindi belt in the north.
https://trip-scan.biz
трипскан вход
When India hosted world leaders for the 2023 G20 summit in New Delhi, invitations were sent out from “Bharat” – the Sanskrit or Hindi name for the country – instead of “India,” fueling speculation that the government aims to ultimately phase out the country’s English designation altogether.
Modi’s critics have been quick to note his political motives behind these moves.
With its roots in the Rashtriya Swayamsevak Sangh (RSS), a right-wing organization that advocates Hindu hegemony within India, the BJP’s language policies resonate with many in a country where nearly 80% of people are Hindu.
Analysts say the BJP is seeking to capitalize on this demographic by promoting language policies that strengthen its support base in the north.
According to Rita Kothari, an English professor from Ashoka University, the government “is certainly interested in homogenizing the country and making Hindi more widespread.”
But that policy can also backfire – in part because many regions, such as Marathi-speaking Maharashtra in the west – are staunchly proud of their local language.
The violent clashes in the state’s megacity Mumbai earlier this month were sparked by the regional government’s controversial decision to make Hindi a compulsory third language in public primary schools.
Pushback and protest has also been especially strong in the south, where English and regional languages such as Tamil, Telugu, and Kannada are valued as symbols of local identity and autonomy.
JamesGop
18 Sep 25 at 9:50 am
микрозайм все [url=https://zaimy-15.ru/]https://zaimy-15.ru/[/url] .
zaimi_wypn
18 Sep 25 at 9:50 am
купить техникум диплом [url=http://educ-ua7.ru/]купить техникум диплом[/url] .
Diplomi_qqEr
18 Sep 25 at 9:51 am
электрокарниз цена [url=http://www.razdvizhnoj-elektrokarniz.ru]http://www.razdvizhnoj-elektrokarniz.ru[/url] .
razdvijnoi elektrokarniz_duei
18 Sep 25 at 9:53 am
В этом информативном тексте представлены захватывающие события и факты, которые заставят вас задуматься. Мы обращаем внимание на важные моменты, которые часто остаются незамеченными, и предлагаем новые перспективы на привычные вещи. Подготовьтесь к тому, чтобы быть поглощенным увлекательными рассказами!
Неизвестные факты о… – https://www.hotel-sugano.com/bbs/sugano.cgi/sosh13.pascal.ru/forum/www.skitour.su/sinopipefittings.com/e_Feedback/datasphere.ru/club/user/12/blog/2477/datasphere.ru/club/user/12/blog/2477/www.tovery.net/sugano.cgi?page40=val
JoshuaZem
18 Sep 25 at 9:54 am
диплом купить с занесением в реестр [url=http://educ-ua14.ru]диплом купить с занесением в реестр[/url] .
Diplomi_aqkl
18 Sep 25 at 9:55 am
Эта статья полна интересного контента, который побудит вас исследовать новые горизонты. Мы собрали полезные факты и удивительные истории, которые обогащают ваше понимание темы. Читайте, погружайтесь в детали и наслаждайтесь процессом изучения!
Жми сюда — получишь ответ – https://lsconsultings.com/2022/09/24/ciao-mondo
JeffreySog
18 Sep 25 at 9:56 am
выравнивание участка трактором цена
выравнивание участка трактором цена
18 Sep 25 at 9:57 am
Эта информационная заметка содержит увлекательные сведения, которые могут вас удивить! Мы собрали интересные факты, которые сделают вашу жизнь ярче и полнее. Узнайте нечто новое о привычных аспектах повседневности и откройте для себя удивительный мир информации.
Открой скрытое – https://www.marioferracinarchitettura.it/tony-kushner-at-peace-not-exactly-but-close
ArthurFurse
18 Sep 25 at 9:59 am
J’adore le retour de Boomerang Casino, c’est un casino en ligne qui revient comme un boomerang lance. propose un ricochet de divertissement qui seduit. avec des slots qui bouclent comme des arcs. Le service client du casino est un arc maitre. resonnant comme une boucle parfaite. se deroulent comme une rhapsodie de ricochets. occasionnellement j’aimerais plus de promotions de casino qui bouclent comme un boomerang. En fin de compte, Boomerang Casino enchante avec une rhapsodie de jeux pour les virtuoses des jeux! A noter l’interface du casino est fluide et revient comme un boomerang. cadence l’aventure avec une rhapsodie de ricochets.
boomerang geant casino|
twirlshadowlynx2zef
18 Sep 25 at 9:59 am
официальные займы онлайн на карту бесплатно [url=http://zaimy-15.ru]http://zaimy-15.ru[/url] .
zaimi_napn
18 Sep 25 at 10:00 am
раздвижной электрокарниз купить [url=http://www.razdvizhnoj-elektrokarniz.ru]http://www.razdvizhnoj-elektrokarniz.ru[/url] .
razdvijnoi elektrokarniz_qwei
18 Sep 25 at 10:00 am
buy xtc prague prague plug
prague-drugs-869
18 Sep 25 at 10:01 am
карниз раздвижной [url=www.razdvizhnoj-elektrokarniz.ru]www.razdvizhnoj-elektrokarniz.ru[/url] .
razdvijnoi elektrokarniz_crei
18 Sep 25 at 10:04 am
https://www.montessorijobsuk.co.uk/author/habvvegu/
Timothyces
18 Sep 25 at 10:05 am
расчистка участка пней
расчистка участка пней
18 Sep 25 at 10:06 am
Dragon Money – безопасная и удобная платформа с увлекательными слотами и живыми дилерами
dragon money официальный сайт
Haroldicope
18 Sep 25 at 10:08 am
В этом информативном тексте представлены захватывающие события и факты, которые заставят вас задуматься. Мы обращаем внимание на важные моменты, которые часто остаются незамеченными, и предлагаем новые перспективы на привычные вещи. Подготовьтесь к тому, чтобы быть поглощенным увлекательными рассказами!
Что скрывают от вас? – https://sierraleonelawyers.com/understanding-legal-fees-demystifying-the-cost-of-legal-services
Roberttuh
18 Sep 25 at 10:08 am
все займы ру [url=www.zaimy-15.ru]www.zaimy-15.ru[/url] .
zaimi_yspn
18 Sep 25 at 10:08 am
электрокарнизы цена [url=https://razdvizhnoj-elektrokarniz.ru]https://razdvizhnoj-elektrokarniz.ru[/url] .
razdvijnoi elektrokarniz_yaei
18 Sep 25 at 10:09 am
Estou alucinado com DonaldBet Casino, tem um ritmo de jogo que danca como um acrobata. As opcoes sao ricas e reluzem como malabares. incluindo mesas com charme de picadeiro. O suporte e um mestre de cerimonias. disponivel por chat ou e-mail. Os saques voam como um acrobata. porem as ofertas podiam ser mais generosas. Resumindo, DonaldBet Casino e um cassino online que e um circo de diversao para os cacadores de vitorias malabaristicas! Como extra o visual e uma explosao de lonas. dando vontade de voltar como um trapezista.
donaldbet logo|
flickerzippyowl5zef
18 Sep 25 at 10:10 am