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!
I have been browsing online greater than three hours as of late, but I never discovered any attention-grabbing article like yours.
It is beautiful price enough for me. Personally, if all web
owners and bloggers made excellent content as you did, the net
will be much more useful than ever before.
شهریه دانشگاه آزاد پرستاری ۱۴۰۴
6 Sep 25 at 12:05 pm
Индивидуальный подход: каждый пациент уникален, поэтому мы разрабатываем индивидуальный план лечения, учитывающий вид зависимости, стадию заболевания и особенности здоровья пациента.
Исследовать вопрос подробнее – [url=https://srochno-vyvod-iz-zapoya.ru/vyvod-iz-zapoya-v-kruglosutochno-v-ufe.ru/]вывод из запоя в стационаре[/url]
JesusGes
6 Sep 25 at 12:05 pm
технического аудита сайта [url=https://internet-agentstvo-prodvizhenie-sajtov-seo.ru/]https://internet-agentstvo-prodvizhenie-sajtov-seo.ru/[/url] .
internet agentstvo prodvijenie saitov seo_duot
6 Sep 25 at 12:06 pm
https://bikersrights.com/articles/le-code-promo-1xbet-bonus.html
hyazihx
6 Sep 25 at 12:07 pm
I really like your blog.. very nice colors & theme.
Did you design this website yourself or did you hire someone to do
it for you? Plz reply as I’m looking to design my own blog and
would like to find out where u got this from.
many thanks
learn more
6 Sep 25 at 12:09 pm
kraken onion зеркала kraken onion, kraken onion ссылка, kraken onion зеркала, kraken рабочая ссылка onion, сайт kraken onion, kraken darknet, kraken darknet market, kraken darknet ссылка, сайт kraken darknet, kraken актуальные ссылки, кракен ссылка kraken, kraken официальные ссылки, kraken ссылка тор, kraken ссылка зеркало, kraken ссылка на сайт, kraken онион, kraken онион тор, кракен онион, кракен онион тор, кракен онион зеркало, кракен даркнет маркет, кракен darknet, кракен onion, кракен ссылка onion, кракен onion сайт, kra ссылка, kraken сайт, kraken актуальные ссылки, kraken зеркало, kraken ссылка зеркало, kraken зеркало рабочее, актуальные зеркала kraken, kraken сайт зеркала, kraken маркетплейс зеркало, кракен ссылка, кракен даркнет
RichardPep
6 Sep 25 at 12:09 pm
блог seo агентства [url=http://statyi-o-marketinge1.ru]http://statyi-o-marketinge1.ru[/url] .
stati o marketinge_kwot
6 Sep 25 at 12:09 pm
https://www.grepmed.com/noficiidro
Richardguers
6 Sep 25 at 12:13 pm
глубокий комлексный аудит сайта [url=http://internet-agentstvo-prodvizhenie-sajtov-seo.ru]http://internet-agentstvo-prodvizhenie-sajtov-seo.ru[/url] .
internet agentstvo prodvijenie saitov seo_hxot
6 Sep 25 at 12:14 pm
Наркологический центр “Луч Надежды” — это место, где можно найти поддержку и помощь, даже когда кажется, что выход потерян. Наша команда врачей-наркологов, психологов и психотерапевтов использует современные методы лечения и реабилитации, помогая пациентам вернуть трезвость и полноценную жизнь. Мы стремимся не только к устранению симптомов, но и к выявлению причин заболевания, давая пациентам необходимые инструменты для борьбы с тягой к психоактивным веществам и формированию новых жизненных установок.
Исследовать вопрос подробнее – [url=https://srochno-vyvod-iz-zapoya.ru/vyvod-iz-zapoya-cena-v-ufe.ru/]вывод из запоя в стационаре[/url]
Raymondben
6 Sep 25 at 12:20 pm
What’s up, for all time i used to check web site posts here early in the dawn, for the reason that i love
to learn more and more.
miniblox online
6 Sep 25 at 12:20 pm
seo продвижение и раскрутка сайта [url=https://www.internet-agentstvo-prodvizhenie-sajtov-seo.ru]seo продвижение и раскрутка сайта[/url] .
internet agentstvo prodvijenie saitov seo_xnot
6 Sep 25 at 12:22 pm
seo продвижение и раскрутка сайта [url=www.internet-agentstvo-prodvizhenie-sajtov-seo.ru/]seo продвижение и раскрутка сайта[/url] .
internet agentstvo prodvijenie saitov seo_zgot
6 Sep 25 at 12:26 pm
โพสต์นี้ น่าสนใจดี ค่ะ
ผม เคยติดตามเรื่องนี้จากหลายแหล่ง ประเด็นที่ใกล้เคียงกัน
ดูต่อได้ที่ Ismael
เหมาะกับคนที่สนใจเรื่องนี้
เพราะอธิบายไว้ละเอียด
ขอบคุณที่แชร์ ข้อมูลที่มีประโยชน์
นี้
อยากเห็นการนำเสนอในหัวข้ออื่นๆ ด้วย
Ismael
6 Sep 25 at 12:27 pm
диплом техникум купить [url=https://www.educ-ua7.ru]диплом техникум купить[/url] .
Diplomi_xjEr
6 Sep 25 at 12:30 pm
глубокий комлексный аудит сайта [url=https://www.internet-agentstvo-prodvizhenie-sajtov-seo.ru]https://www.internet-agentstvo-prodvizhenie-sajtov-seo.ru[/url] .
internet agentstvo prodvijenie saitov seo_lkot
6 Sep 25 at 12:31 pm
https://tap.bio/@hargatoto# hargatoto
Josephagody
6 Sep 25 at 12:32 pm
Инфузии выполняются с помощью автоматизированных насосов, позволяющих скорректировать скорость введения в зависимости от показателей безопасности.
Подробнее – https://medicinskij-vyvod-iz-zapoya.ru/vyvod-iz-zapoya-czena-krasnoyarsk
Robertwheda
6 Sep 25 at 12:33 pm
darknet markets 2025 onion dark website nexus link [url=https://darknetmarketstore.com/ ]darknet links [/url]
Jamespem
6 Sep 25 at 12:36 pm
https://form.jotform.com/252431390782053
Richardguers
6 Sep 25 at 12:36 pm
kraken darknet kraken onion, kraken onion ссылка, kraken onion зеркала, kraken рабочая ссылка onion, сайт kraken onion, kraken darknet, kraken darknet market, kraken darknet ссылка, сайт kraken darknet, kraken актуальные ссылки, кракен ссылка kraken, kraken официальные ссылки, kraken ссылка тор, kraken ссылка зеркало, kraken ссылка на сайт, kraken онион, kraken онион тор, кракен онион, кракен онион тор, кракен онион зеркало, кракен даркнет маркет, кракен darknet, кракен onion, кракен ссылка onion, кракен onion сайт, kra ссылка, kraken сайт, kraken актуальные ссылки, kraken зеркало, kraken ссылка зеркало, kraken зеркало рабочее, актуальные зеркала kraken, kraken сайт зеркала, kraken маркетплейс зеркало, кракен ссылка, кракен даркнет
RichardPep
6 Sep 25 at 12:37 pm
В Люберцах клиника Stop Alko предлагает капельницы от запоя не только с детоксикацией, но и с поддержкой печени, сердца и нервной системы.
Исследовать вопрос подробнее – [url=https://kapelnica-ot-zapoya-lyubercy11.ru/]врача капельницу от запоя в подольске[/url]
Thomasfaf
6 Sep 25 at 12:38 pm
продвинуть сайт в москве [url=https://internet-agentstvo-prodvizhenie-sajtov-seo.ru]https://internet-agentstvo-prodvizhenie-sajtov-seo.ru[/url] .
internet agentstvo prodvijenie saitov seo_mqot
6 Sep 25 at 12:39 pm
I don’t know if it’s just me or if everyone else experiencing issues with your blog.
It appears like some of the text within your posts are running off
the screen. Can someone else please comment and let me know if this is happening to them too?
This may be a issue with my web browser because I’ve had this happen previously.
Many thanks
SEO
6 Sep 25 at 12:41 pm
Hi would you mind sharing which blog platform you’re using?
I’m planning to start my own blog soon but I’m having a hard time
deciding between BlogEngine/Wordpress/B2evolution and Drupal.
The reason I ask is because your design and style seems different then most blogs and I’m
looking for something completely unique.
P.S Sorry for getting off-topic but I had to ask!
construction administration nearby
6 Sep 25 at 12:43 pm
Je kiffe a mort FatPirate, ca donne une energie de pirate dejantee. Il y a un ocean de titres varies, proposant des sessions live ultra-intenses. Le crew assure un suivi de ouf, avec une aide qui dechire. Les retraits sont rapides comme une tempete, mais bon des recompenses en plus ca serait la cerise. En gros, FatPirate offre une experience de ouf pour les fans de casinos en ligne ! En prime le design est style et accrocheur, ajoute un max de swag.
fatpirate casino|
wildpickle3zef
6 Sep 25 at 12:44 pm
заказать продвижение сайта в москве [url=https://www.internet-agentstvo-prodvizhenie-sajtov-seo.ru]заказать продвижение сайта в москве[/url] .
internet agentstvo prodvijenie saitov seo_anot
6 Sep 25 at 12:44 pm
где можно купить аттестат [url=http://educ-ua16.ru]где можно купить аттестат[/url] .
Diplomi_vzmi
6 Sep 25 at 12:45 pm
продвижение сайта [url=www.internet-agentstvo-prodvizhenie-sajtov-seo.ru/]продвижение сайта[/url] .
internet agentstvo prodvijenie saitov seo_ksot
6 Sep 25 at 12:49 pm
частный seo оптимизатор [url=https://poiskovoe-seo-v-moskve.ru]https://poiskovoe-seo-v-moskve.ru[/url] .
poiskovoe seo v moskve_ixPr
6 Sep 25 at 12:52 pm
диплом техникума с отличием купить [url=https://educ-ua7.ru]https://educ-ua7.ru[/url] .
Diplomi_esEr
6 Sep 25 at 12:53 pm
сделать аудит сайта цена [url=http://internet-agentstvo-prodvizhenie-sajtov-seo.ru]http://internet-agentstvo-prodvizhenie-sajtov-seo.ru[/url] .
internet agentstvo prodvijenie saitov seo_bgot
6 Sep 25 at 12:53 pm
купить диплом о высшем образовании в украине [url=https://www.educ-ua18.ru]купить диплом о высшем образовании в украине[/url] .
Diplomi_brPi
6 Sep 25 at 12:55 pm
I quite like reading a post that will make men and women think.
Also, many thanks for allowing me to comment!
جواب کنکور فنی حرفه ای کی میاد
6 Sep 25 at 12:55 pm
Hello would you mind sharing which blog platform you’re working with?
I’m planning to start my own blog soon but I’m having a tough time deciding between BlogEngine/Wordpress/B2evolution and Drupal.
The reason I ask is because your design seems different then most blogs and I’m looking for something completely unique.
P.S Apologies for being off-topic but I had to ask!
نظرات دانشجویان پزشکی تعهدی
6 Sep 25 at 12:57 pm
CoffeeRoom — интернет-магазин кофе и чая с доставкой по Беларуси. Ищете кофе в зернах купить? coffeeroom.by можно купить зерновой и молотый кофе, капсулы, чалды, чай, сиропы, подарочные наборы, а также кофемолки и аксессуары. Регулярные акции, свежая обжарка, быстрая доставка по Минску и РБ, удобная оплата.
ruwolpeedo
6 Sep 25 at 12:59 pm
https://form.jotform.com/252424182737054
Richardguers
6 Sep 25 at 12:59 pm
раскрутка и продвижение сайта [url=https://www.poiskovoe-seo-v-moskve.ru]раскрутка и продвижение сайта[/url] .
poiskovoe seo v moskve_pxPr
6 Sep 25 at 1:03 pm
posso ordinare seroquel economico online
costo di seroquel online
6 Sep 25 at 1:06 pm
заказать анализ сайта [url=internet-agentstvo-prodvizhenie-sajtov-seo.ru]заказать анализ сайта[/url] .
internet agentstvo prodvijenie saitov seo_pcot
6 Sep 25 at 1:06 pm
seo продвижение и раскрутка сайта [url=https://internet-agentstvo-prodvizhenie-sajtov-seo.ru]seo продвижение и раскрутка сайта[/url] .
internet agentstvo prodvijenie saitov seo_afot
6 Sep 25 at 1:09 pm
регистрация в мостбет [url=https://www.mostbet4159.ru]регистрация в мостбет[/url]
mostbet_yien
6 Sep 25 at 1:11 pm
кракен onion сайт kraken onion, kraken onion ссылка, kraken onion зеркала, kraken рабочая ссылка onion, сайт kraken onion, kraken darknet, kraken darknet market, kraken darknet ссылка, сайт kraken darknet, kraken актуальные ссылки, кракен ссылка kraken, kraken официальные ссылки, kraken ссылка тор, kraken ссылка зеркало, kraken ссылка на сайт, kraken онион, kraken онион тор, кракен онион, кракен онион тор, кракен онион зеркало, кракен даркнет маркет, кракен darknet, кракен onion, кракен ссылка onion, кракен onion сайт, kra ссылка, kraken сайт, kraken актуальные ссылки, kraken зеркало, kraken ссылка зеркало, kraken зеркало рабочее, актуальные зеркала kraken, kraken сайт зеркала, kraken маркетплейс зеркало, кракен ссылка, кракен даркнет
RichardPep
6 Sep 25 at 1:12 pm
интернет продвижение москва [url=internet-agentstvo-prodvizhenie-sajtov-seo.ru]интернет продвижение москва[/url] .
internet agentstvo prodvijenie saitov seo_gjot
6 Sep 25 at 1:12 pm
kraken маркетплейс зеркало kraken onion, kraken onion ссылка, kraken onion зеркала, kraken рабочая ссылка onion, сайт kraken onion, kraken darknet, kraken darknet market, kraken darknet ссылка, сайт kraken darknet, kraken актуальные ссылки, кракен ссылка kraken, kraken официальные ссылки, kraken ссылка тор, kraken ссылка зеркало, kraken ссылка на сайт, kraken онион, kraken онион тор, кракен онион, кракен онион тор, кракен онион зеркало, кракен даркнет маркет, кракен darknet, кракен onion, кракен ссылка onion, кракен onion сайт, kra ссылка, kraken сайт, kraken актуальные ссылки, kraken зеркало, kraken ссылка зеркало, kraken зеркало рабочее, актуальные зеркала kraken, kraken сайт зеркала, kraken маркетплейс зеркало, кракен ссылка, кракен даркнет
RichardPep
6 Sep 25 at 1:14 pm
интернет продвижение москва [url=www.poiskovoe-seo-v-moskve.ru]www.poiskovoe-seo-v-moskve.ru[/url] .
poiskovoe seo v moskve_ymPr
6 Sep 25 at 1:14 pm
Thank you for the good writeup. It in fact was a amusement account it.
Look advanced to far added agreeable from you!
However, how can we communicate?
check
6 Sep 25 at 1:15 pm
купить диплом в запорожье [url=https://educ-ua7.ru]купить диплом в запорожье[/url] .
Diplomi_oxEr
6 Sep 25 at 1:15 pm
https://www.te-in.ru/
Rolandmow
6 Sep 25 at 1:16 pm
https://choir.km.ua/termo/inc/kak_sdelaty_prud_v_sadu.html
https://choir.km.ua/termo/inc/kak_sdelaty_prud_v_sadu.html
6 Sep 25 at 1:17 pm