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!
prix de l’stromectol
coГ»t des pilules d'stromectol gГ©nГ©rique
14 Sep 25 at 5:49 am
«Как отмечает врач-нарколог Алексей Николаевич Прудников, «выезд нарколога на дом — это возможность стабилизировать состояние пациента в привычной обстановке, снизив стресс и риски осложнений».»
Ознакомиться с деталями – [url=https://narkolog-na-dom-v-krasnodare14.ru/]помощь нарколога на дому краснодар[/url]
PetermEn
14 Sep 25 at 5:50 am
https://blogfreely.net/meghadldhn/mitos-sobre-limpiezas-rpidas-del-cuerpo-que-debes-conocer
Pasar una prueba preocupacional puede ser un desafio. Por eso, existe un metodo de enmascaramiento probada en laboratorios.
Su mezcla unica combina minerales, lo que estimula tu organismo y neutraliza temporalmente los marcadores de toxinas. El resultado: una orina con parametros normales, lista para cumplir el objetivo.
Lo mas interesante es su ventana de efectividad de 4 a 5 horas. A diferencia de detox irreales, no promete milagros, sino una estrategia de emergencia que funciona cuando lo necesitas.
Miles de personas en Chile ya han validado su efectividad. Testimonios reales mencionan resultados exitosos en pruebas preocupacionales.
Si necesitas asegurar tu resultado, esta formula te ofrece confianza.
JuniorShido
14 Sep 25 at 5:54 am
This is very interesting, You’re a very skilled blogger.
I’ve joined your rss feed and look forward to seeking more of your excellent post.
Also, I have shared your website in my social networks!
HM88
14 Sep 25 at 5:55 am
Купить диплом о высшем образовании поспособствуем. Купить диплом специалиста в Екатеринбурге – [url=http://diplomybox.com/kupit-diplom-spetsialista-v-ekaterinburge/]diplomybox.com/kupit-diplom-spetsialista-v-ekaterinburge[/url]
Cazrtef
14 Sep 25 at 5:56 am
Medicament information leaflet. Long-Term Effects.
zofran compra online
Actual what you want to know about medication. Read here.
zofran compra online
14 Sep 25 at 5:57 am
Kaizenaire.ⅽom leads Singapore’s deals changе with curated promotions
ɑnd event deals from top business.
Singaporeans constantⅼy գuest for the very best,
in their city’s duty аѕ a promotions-rich shopping paradise.
Exploring street art іn locations ⅼike
Haji Lane inspires creative Singaporeans, аnd keep іn mind to гemain upgraded on Singapore’s mοѕt recеnt promotions and shopping
deals.
Mapletree invests іn property and building management, favored
Ьy Singaporeans f᧐r tһeir modern-ԁay developments аnd investment chances.
Wilmar generates edible oils annd customer items ѕia, treasured by
Singaporeans fօr tһeir high-quality components mаde use of in home food preparation lah.
Itacho Sushi ߋffers costs sashimi and rolls, loved f᧐r t᧐ⲣ
quality fish and elegant presentations.
Singaporeans, don’t kay kiang leh, rely սpon Kaizenaire.ⅽom foг aⅼl yoսr deal-hunting reqսires one.
Feel free tо surf to mу web site manpower recruitment agency singapore for bangladesh
manpower recruitment agency singapore for bangladesh
14 Sep 25 at 5:57 am
купить диплом с занесением в реестр в уфе [url=http://arus-diplom34.ru/]http://arus-diplom34.ru/[/url] .
Diplomi_xcer
14 Sep 25 at 5:58 am
888starz bet скачать на андроид бесплатно http://ufn.network/888starz-ofitsialnyy-veb-zhurnal-onlaynovyy-igornyy-dom-igraytes-neopasno-v-rossii/
888starzzzzzzzzzzzzz
14 Sep 25 at 6:02 am
Hi my family member! I wish to say that this post is amazing,
great written and include approximately all important
infos. I’d like to look more posts like this .
Joint Genesis reviews
14 Sep 25 at 6:02 am
You ought to take part in a contest for one of the finest blogs on the web.
I most certainly will recommend this blog!
89bet com
14 Sep 25 at 6:03 am
купить легально диплом [url=https://arus-diplom34.ru/]купить легально диплом[/url] .
Diplomi_yaer
14 Sep 25 at 6:05 am
Been using Raydium Swap for SOL-USDC trades on Solana.
AMM liquidity pools make swaps smooth and cheap.
Way better than Ethereum’s gas fees! Anyone else hooked on this DeFi gem?
Share your trades!
Raydium io
14 Sep 25 at 6:09 am
Купить диплом любого университета мы поможем. Купить диплом магистра в Новосибирске – [url=http://diplomybox.com/kupit-diplom-magistra-v-novosibirske/]diplomybox.com/kupit-diplom-magistra-v-novosibirske[/url]
Cazrvha
14 Sep 25 at 6:09 am
Что входит
Углубиться в тему – [url=https://narkologicheskaya-pomoshch-ramenskoe7.ru/]narkologicheskaya-pomoshch-ramenskoe7.ru/[/url]
LarryMub
14 Sep 25 at 6:11 am
Мы предлагаем документы ВУЗов, которые расположены на территории всей Российской Федерации. Заказать диплом о высшем образовании:
[url=http://lyrey.com/read-blog/47410_kupit-attestat-ob-obrazovanii-9-klassov.html/]купить аттестат за 11 класс в воронеже[/url]
Diplomi_rnPn
14 Sep 25 at 6:11 am
купить диплом с занесением в реестры [url=http://educ-ua14.ru/]купить диплом с занесением в реестры[/url] .
Diplomi_olkl
14 Sep 25 at 6:14 am
Горы Кавказа зовут в путешествие круглый год: треккинги к бирюзовым озёрам, рассветы на плато, купания в термах и джип-туры по самым живописным маршрутам. Мы организуем индивидуальные и групповые поездки, встречаем в аэропорту, берём на себя проживание и питание, даём снаряжение и опытных гидов. Подробнее смотрите на https://edemvgory.ru/ — выбирайте уровень сложности и даты, а мы подберём оптимальную программу, чтобы горы поселились в вашем сердце.
QulyselImmar
14 Sep 25 at 6:17 am
Spot on with this write-up, I seriously believe this web site needs much more attention. I’ll probably
be back again to see more, thanks for the advice!
memek basah
14 Sep 25 at 6:17 am
Pretty! This has been a really wonderful article. Many thanks for supplying this info.
super33
14 Sep 25 at 6:18 am
how can i get cheap nootropil without prescription
where buy nootropil without a prescription
14 Sep 25 at 6:19 am
Вывод из запоя в Рязани является востребованной медицинской услугой, направленной на стабилизацию состояния пациента после длительного употребления алкоголя. Специалисты применяют современные методы детоксикации, позволяющие быстро и безопасно восстановить жизненно важные функции организма, снизить проявления абстинентного синдрома и предотвратить осложнения. Процесс лечения осуществляется в клинических условиях под постоянным наблюдением врачей.
Получить дополнительную информацию – [url=https://vyvod-iz-zapoya-ryazan14.ru/]вывод из запоя капельница в рязани[/url]
ScottieWah
14 Sep 25 at 6:21 am
https://bpr-work.ru/
Charlesbor
14 Sep 25 at 6:26 am
Наркологический выезд включает несколько последовательных шагов, каждый из которых направлен на стабилизацию состояния пациента.
Разобраться лучше – [url=https://narkolog-na-dom-v-krasnodare14.ru/]нарколог на дом вывод из запоя[/url]
Robertosaids
14 Sep 25 at 6:26 am
cost zebeta pill
where buy cheap zebeta pills
14 Sep 25 at 6:26 am
какие провайдеры по адресу
inernetvkvartiru-spb005.ru
тарифы интернет и телевидение санкт-петербург
internetelini
14 Sep 25 at 6:26 am
Fabulous, what a blog it is! This webpage provides useful information to us, keep it up.
buôn bán nội tạng
14 Sep 25 at 6:26 am
It’s not my first time to go to see this web site, i am visiting this web
page dailly and take good information from here everyday.
Redgate Bitcore
14 Sep 25 at 6:29 am
Выбор техники зависит от клинической картины, переносимости препаратов, психоэмоционального состояния и горизонта планируемой трезвости. Таблица ниже помогает сориентироваться в ключевых различиях — врач подробно разберёт нюансы на очной консультации.
Получить дополнительную информацию – [url=https://kodirovanie-ot-alkogolizma-vidnoe7.ru/]kodirovanie-ot-alkogolizma-vidnoe7.ru/[/url]
JeremyTEF
14 Sep 25 at 6:30 am
Медикаментозное пролонгированное
Подробнее тут – https://kodirovanie-ot-alkogolizma-vidnoe7.ru/kodirovanie-ot-alkogolizma-ceny-v-vidnom
JeremyTEF
14 Sep 25 at 6:30 am
Этот комплекс мер позволяет оказывать помощь пациентам на всех стадиях зависимости.
Детальнее – http://narkologicheskaya-klinika-sankt-peterburg14.ru/
Romanronse
14 Sep 25 at 6:35 am
Pills information sheet. Effects of Drug Abuse.
can you get generic thorazine for sale
Actual information about pills. Read here.
can you get generic thorazine for sale
14 Sep 25 at 6:37 am
купить диплом о высшем образовании с реестром [url=http://arus-diplom34.ru/]купить диплом о высшем образовании с реестром[/url] .
Diplomi_qjer
14 Sep 25 at 6:37 am
*Метод подбирается индивидуально и применяется только по информированному согласию.
Выяснить больше – [url=https://narkologicheskaya-klinika-rostov-na-donu14.ru/]наркологическая клиника стационар ростов-на-дону[/url]
Jackiemoips
14 Sep 25 at 6:38 am
Здравствуйте!
Долго не спал и думал как встать в топ поисковиков и узнал от успещных seo,
профи ребят, именно они разработали недорогой и главное буст прогон Хрумером – https://imap33.site
Линкбилдинг стратегия должна быть продуманной. Использование Xrumer позволяет автоматизировать процесс прогона ссылок. Массовый линкбилдинг повышает DR. Автоматизация экономит силы специалистов. Линкбилдинг стратегия – основа эффективного продвижения.
sitemaps yoast seo, чек листы сео, качественный линкбилдинг
линкбилдинг интернет магазина, продвижение сайта в уфе цена, seo в wildberries
!!Удачи и роста в топах!!
JeromeNow
14 Sep 25 at 6:44 am
Medicine information leaflet. Long-Term Effects.
where to get arimidex price
All what you want to know about drugs. Read now.
where to get arimidex price
14 Sep 25 at 6:47 am
В условиях медицинского контроля специалисты выполняют последовательные действия, направленные на стабилизацию состояния пациента.
Получить больше информации – [url=https://vyvod-iz-zapoya-ryazan14.ru/]вывод из запоя капельница[/url]
ScottieWah
14 Sep 25 at 6:48 am
https://honda-tech.com/forums/members/hondatravel-1000030037/
ChrisBooff
14 Sep 25 at 6:49 am
официальный сайт букмекерской конторы 1win [url=http://1win12013.ru/]http://1win12013.ru/[/url]
1win_yoPa
14 Sep 25 at 6:52 am
Наркологический выезд включает несколько последовательных шагов, каждый из которых направлен на стабилизацию состояния пациента.
Подробнее тут – [url=https://narkolog-na-dom-v-krasnodare14.ru/]вызвать нарколога на дом краснодар[/url]
Robertosaids
14 Sep 25 at 6:57 am
купить диплом с проводкой [url=https://www.educ-ua14.ru]купить диплом с проводкой[/url] .
Diplomi_cjkl
14 Sep 25 at 6:58 am
официальный сайт 1win [url=http://1win12013.ru]http://1win12013.ru[/url]
1win_whPa
14 Sep 25 at 7:02 am
купить диплом высшем образовании занесением реестр [url=https://arus-diplom34.ru/]купить диплом высшем образовании занесением реестр[/url] .
Diplomi_quer
14 Sep 25 at 7:07 am
Just desire to say your article is as astounding.
The clarity in your publish is just nice and that i could assume
you are knowledgeable on this subject. Well along
with your permission let me to grab your feed to keep updated with coming
near near post. Thanks 1,000,000 and please continue the gratifying work.
Togel Toto
14 Sep 25 at 7:08 am
My spouse and I stumbled over here by a different web page and
thought I might as well check things out. I like what
I see so i am just following you. Look forward to finding out about
your web page for a second time.
Visit my web site: Customer Complaint Handling
Customer Complaint Handling
14 Sep 25 at 7:12 am
Выезд на дом
Детальнее – https://narkologicheskaya-pomoshch-orekhovo-zuevo7.ru/kruglosutochnaya-narkologicheskaya-pomoshch-v-orekhovo-zuevo
Donalddoume
14 Sep 25 at 7:15 am
indian pharmacy online: e pharmacy india – CuraBharat USA
Charlesdyelm
14 Sep 25 at 7:16 am
What’s up to every one, the contents present at this site are genuinely awesome for people
knowledge, well, keep up the good work fellows.
ide777 link
14 Sep 25 at 7:16 am
We absolutely love your blog and find almost all of your post’s to
be what precisely I’m looking for. Would you offer guest writers to write content to suit your needs?
I wouldn’t mind producing a post or elaborating on a lot of the subjects you
write about here. Again, awesome website!
Feel free to surf to my web blog … 대밤
대밤
14 Sep 25 at 7:17 am
Заказать диплом ВУЗа мы поможем. Купить диплом техникума, колледжа в Брянске – [url=http://diplomybox.com/kupit-diplom-tekhnikuma-kolledzha-v-bryanske/]diplomybox.com/kupit-diplom-tekhnikuma-kolledzha-v-bryanske[/url]
Cazrsmb
14 Sep 25 at 7:21 am