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!
диплом техникума с отличием купить [url=http://educ-ua10.ru/]http://educ-ua10.ru/[/url] .
Diplomi_lsKl
7 Sep 25 at 10:49 pm
украина свидетельство о браке купить [url=http://educ-ua5.ru]http://educ-ua5.ru[/url] .
Diplomi_ufKl
7 Sep 25 at 10:50 pm
Je suis accro a LeonBet Casino, ca pulse avec une energie de casino indomptable. Il y a un raz-de-maree de jeux de casino captivants, proposant des slots de casino a theme audacieux. Le personnel du casino offre un accompagnement rugissant, proposant des solutions claires et instantanees. Les transactions du casino sont simples comme un rugissement, quand meme plus de tours gratuits au casino ce serait feroce. Au final, LeonBet Casino promet un divertissement de casino rugissant pour les chasseurs du casino ! Bonus la plateforme du casino brille par son style indomptable, ajoute une touche de puissance au casino.
leonbet gr|
whimsypelican7zef
7 Sep 25 at 10:50 pm
купить проведенный диплом Украина [url=https://www.educ-ua14.ru]https://www.educ-ua14.ru[/url] .
Diplomi_uzkl
7 Sep 25 at 10:51 pm
Новые актуальные iherb промокод кэшбэк для выгодных покупок! Скидки на витамины, БАДы, косметику и товары для здоровья. Экономьте до 30% на заказах, используйте проверенные купоны и наслаждайтесь выгодным шопингом.
promocod-iherb-514
7 Sep 25 at 10:53 pm
экстренный вывод из запоя
vivod-iz-zapoya-kaluga012.ru
вывод из запоя калуга
lecheniekalugaNeT
7 Sep 25 at 10:53 pm
как купить диплом о высшем образовании с занесением в реестр отзывы [url=https://educ-ua11.ru/]https://educ-ua11.ru/[/url] .
Diplomi_tzPi
7 Sep 25 at 10:55 pm
That is the kind of submit that makes me want to
study more.
actual Gold IRA companies
7 Sep 25 at 10:59 pm
купить диплом техникума Харьков [url=www.educ-ua10.ru]купить диплом техникума Харьков[/url] .
Diplomi_qnKl
7 Sep 25 at 11:00 pm
блог агентства интернет-маркетинга [url=https://www.blog-o-marketinge.ru]https://www.blog-o-marketinge.ru[/url] .
blog o marketinge_vxSn
7 Sep 25 at 11:02 pm
блог про продвижение сайтов [url=http://blog-o-marketinge.ru/]блог про продвижение сайтов[/url] .
blog o marketinge_xeSn
7 Sep 25 at 11:08 pm
В Люберцах всё больше людей доверяют клинике Stop Alko — здесь грамотно подбирают капельницу от запоя с учётом состояния пациента.
Получить дополнительную информацию – [url=https://kapelnica-ot-zapoya-lyubercy12.ru/]капельница от запоя на дому город. московская область[/url]
AnthonyVah
7 Sep 25 at 11:11 pm
https://www.metooo.io/u/68ac4f1d63c6551a88a1f271
BillyDon
7 Sep 25 at 11:12 pm
seo и реклама блог [url=https://blog-o-marketinge.ru/]blog-o-marketinge.ru[/url] .
blog o marketinge_zpSn
7 Sep 25 at 11:17 pm
I like looking through a post that will make people think.
Also, thank you for allowing me to comment!
강남여성전용마사지
7 Sep 25 at 11:17 pm
We absolutely love your blog and find most of your post’s to be exactly
I’m looking for. Does one offer guest writers to write content to suit your
needs? I wouldn’t mind publishing a post or elaborating on most of the subjects you
write concerning here. Again, awesome website!
live draw sdy
7 Sep 25 at 11:19 pm
I blog quite often and I genuinely appreciate your
content. This great article has really peaked my interest.
I’m going to bookmark your blog and keep checking for new
details about once a week. I subscribed to your RSS feed too.
merketing kontol
7 Sep 25 at 11:20 pm
интернет маркетинг статьи [url=http://blog-o-marketinge.ru/]интернет маркетинг статьи[/url] .
blog o marketinge_jaSn
7 Sep 25 at 11:21 pm
провайдеры интернета по адресу
inernetvkvartiru-ekaterinburg004.ru
недорогой интернет екатеринбург
internetelini
7 Sep 25 at 11:23 pm
Mochten Sie ein https://www.immobilien-in-montenegro-fuer-oesterreicher.com kaufen? Tolle Angebote am Meer und in den Bergen. Gro?e Auswahl an Immobilien, Unterstutzung bei der Immobilienauswahl, Transaktionsunterstutzung und Registrierung. Leben Sie in einem Land mit mildem Klima und wunderschoner Natur.
montenegro-575
7 Sep 25 at 11:24 pm
Mochten Sie ein immobilien Montenegro kaufen? Tolle Angebote am Meer und in den Bergen. Gro?e Auswahl an Immobilien, Unterstutzung bei der Immobilienauswahl, Transaktionsunterstutzung und Registrierung. Leben Sie in einem Land mit mildem Klima und wunderschoner Natur.
montenegro-353
7 Sep 25 at 11:26 pm
Mochten Sie ein immobilie Montenegro kaufen? Tolle Angebote am Meer und in den Bergen. Gro?e Auswahl an Immobilien, Unterstutzung bei der Immobilienauswahl, Transaktionsunterstutzung und Registrierung. Leben Sie in einem Land mit mildem Klima und wunderschoner Natur.
montenegro-342
7 Sep 25 at 11:28 pm
What’s up Dear, are you genuinely visiting this web
page on a regular basis, if so afterward you will definitely take nice experience.
Somers Plumbers nearby
7 Sep 25 at 11:28 pm
nexusdarknet site link nexus market link nexus darknet access [url=https://darkmarketsdirectory.com/ ]nexus shop [/url]
BrianWeX
7 Sep 25 at 11:28 pm
что будет если купить диплом о высшем образовании с занесением в реестр [url=http://educ-ua14.ru/]что будет если купить диплом о высшем образовании с занесением в реестр[/url] .
Diplomi_yckl
7 Sep 25 at 11:32 pm
Миссия центра “Луч Надежды” — помогать людям, попавшим в плен зависимости, находить путь к выздоровлению. Мы не ограничиваемся лечением, а делаем акцент на профилактике рецидивов, социальной адаптации пациентов и их возвращении к полноценной, радостной жизни без психоактивных веществ.
Детальнее – [url=https://srochno-vyvod-iz-zapoya.ru/vyvod-iz-zapoya-v-stacionare-v-ufe.ru/]вывод из запоя вызов в уфе[/url]
JesusGes
7 Sep 25 at 11:32 pm
What’s up to every one, it’s in fact a pleasant for me to pay a visit this
web site, it includes valuable Information.
강남토닥이
7 Sep 25 at 11:33 pm
Very rapidly this website will be famous amid all blogging and site-building people, due to it’s fastidious articles or reviews
live draw hk lotto
7 Sep 25 at 11:36 pm
https://www.themeqx.com/forums/users/ncubebudicze/
BillyDon
7 Sep 25 at 11:41 pm
статьи про digital маркетинг [url=https://blog-o-marketinge.ru/]blog-o-marketinge.ru[/url] .
blog o marketinge_kuSn
7 Sep 25 at 11:41 pm
Generally I ⅾo not learn article on blogs, but I ᴡish
to say that this write-ᥙp very forced me tօ check oսt and do so!
Your writing style has been surprised me. Tһank yоu, quite nice post.
Μy web page :: https://www.letmejerk.com
https://www.letmejerk.com
7 Sep 25 at 11:42 pm
купить диплом высшем образовании одессе [url=https://educ-ua3.ru/]купить диплом высшем образовании одессе[/url] .
Diplomi_tmki
7 Sep 25 at 11:44 pm
kratonbet [url=https://linklist.bio/kratonbet777#]kratonbet login[/url] kratonbet
CharlesJam
7 Sep 25 at 11:46 pm
статьи про digital маркетинг [url=www.blog-o-marketinge.ru/]www.blog-o-marketinge.ru/[/url] .
blog o marketinge_tmSn
7 Sep 25 at 11:48 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
7 Sep 25 at 11:51 pm
статьи о маркетинге [url=blog-o-marketinge.ru]статьи о маркетинге[/url] .
blog o marketinge_nySn
7 Sep 25 at 11:53 pm
Refresh Renovation Southwest Charlotte
1251 Arrow Pine Ɗr ⅽ121,
Charlotte, NC 28273, Unitedd Ѕtates
+19803517882
proven 5 step renovation process
proven 5 step renovation process
7 Sep 25 at 11:53 pm
We are a group of volunteers aand opening a neᴡ scheme іn our community.
Your site offered uss ѡith valuable info tto
ѡork on. You hazve dߋne an impressive job аnd
ouur wholke community wiⅼl be grateful tο уօu.
my site https://www.letmejerk.com
https://www.letmejerk.com
7 Sep 25 at 11:54 pm
купить диплом об образовании с реестром [url=educ-ua11.ru]купить диплом об образовании с реестром[/url] .
Diplomi_tkPi
7 Sep 25 at 11:58 pm
KRAKEN – Ваша безопасность и анонимность на vhod-aktual.ru
vhod-aktual.ru — официальный переходник даркнет-маркета Kraken.
Добро пожаловать на kra37.help, где приватность и безопасность являются главным приоритетом. Официальный сайт kraken kra38.at — сохрани список актуальных зеркал. Переходите на vhod-aktual.ru и начните пользоваться прямо сейчас!
кракен, kraken, сайт кракен, ссылка кракен, кракен ссылка, кракен сайт, кракен официальный сайт, официальный сайт кракен, кракен ссылка официальная, кракен актуальная ссылка
+ Полная анонимность и защита данных
Система безопасности KRAKEN обеспечивает полную конфиденциальность. Передовые технологии шифрования для защиты ваших данных и транзакций.
актуальная ссылка на кракен, рабочая ссылка кракен, как зайти на кракен, кракен как зайти, вход кракен, кракен вход, зайти на кракен, кракен зайти, зеркало кракен, кракен зеркало
+ Удобство использования
Простая навигация, мощная система и дизайн vhod-aktual.ru делают использование KRAKEN комфортным на любых устройствах.
кракен рабочее зеркало, рабочее зеркало кракен, зеркала кракен, кракен зеркала, даркнет кракен, кракен даркнет, маркетплейс кракен, кракен маркетплейс, площадка кракен, кракен площадка
+ Гарантии безопасности и круглосуточная поддержка
KRAKEN гарантирует защиту покупателей и продавцов. Служба поддержки kra37.help работает 24/7 для решения любых вопросов.
магазин кракен, кракен магазин, кракен маркет, кракены маркет, кракен даркнет маркет, кракен маркет даркнет, кракен отзывы, кракен сайт что, кракен ссылка тор, ссылка кракен тор
ForrestNug
7 Sep 25 at 11:59 pm
Подбираете медсправку за один день в Москве — оперативно и без похода в клинику? На [url=https://akkred-med.ru]https://akkred-med.ru[/url] можно заказать разные виды справок, от справки 095/у, 027/у до справок комиссии, справок в бассейн, занятий спортом и оформления визы. Подать заявку можно за пару минут, потом — курьерская доставка. Всё законно, без разглашения и без проблем. Все детали на сайте — быстрое оформление справки, заказ через интернет, доставка справки.
Spravkintm
7 Sep 25 at 11:59 pm
Greetings! This is my first visit to your blog! We are a collection of volunteers
and starting a new initiative in a community in the same niche.
Your blog provided us beneficial information to work on. You have done a
outstanding job!
Florian
8 Sep 25 at 12:01 am
Новые актуальные iherb промокод для новых для выгодных покупок! Скидки на витамины, БАДы, косметику и товары для здоровья. Экономьте до 30% на заказах, используйте проверенные купоны и наслаждайтесь выгодным шопингом.
promocod-iherb-313
8 Sep 25 at 12:02 am
You’re so awesome! I do not think I’ve truly read a single thing like that
before. So good to discover somebody with a few genuine thoughts on this topic.
Really.. many thanks for starting this up. This website is one thing that is needed on the internet, someone with a
little originality!
pointed out that
8 Sep 25 at 12:07 am
tor drug market darknet sites nexus darknet url [url=https://privatedarknetmarket.com/ ]dark market url [/url]
Robertalima
8 Sep 25 at 12:09 am
https://pxlmo.com/mLuissaMariatenme
BillyDon
8 Sep 25 at 12:09 am
статьи про маркетинг и seo [url=http://blog-o-marketinge.ru/]http://blog-o-marketinge.ru/[/url] .
blog o marketinge_jzSn
8 Sep 25 at 12:12 am
купить диплом о высшем образовании легально [url=http://educ-ua14.ru]http://educ-ua14.ru[/url] .
Diplomi_rqkl
8 Sep 25 at 12:13 am
Новые актуальные промокод iherb promo для выгодных покупок! Скидки на витамины, БАДы, косметику и товары для здоровья. Экономьте до 30% на заказах, используйте проверенные купоны и наслаждайтесь выгодным шопингом.
promocod-iherb-821
8 Sep 25 at 12:13 am
Современная наркология предлагает два основных формата вывода из запоя:
Детальнее – [url=https://nadezhnyj-vyvod-iz-zapoya.ru/]вывод из запоя дешево санкт-петербруг[/url]
Davidhib
8 Sep 25 at 12:15 am