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=https://zaimy-26.ru]список займов онлайн[/url] .
zaimi_lxSt
15 Oct 25 at 3:51 pm
купить диплом в омске [url=www.rudik-diplom6.ru/]купить диплом в омске[/url] .
Diplomi_tjKr
15 Oct 25 at 3:52 pm
можно купить диплом медсестры [url=https://frei-diplom13.ru]можно купить диплом медсестры[/url] .
Diplomi_dxkt
15 Oct 25 at 3:52 pm
Spinrise Casino
FrankAmoum
15 Oct 25 at 3:52 pm
купить диплом в димитровграде [url=www.rudik-diplom8.ru]купить диплом в димитровграде[/url] .
Diplomi_zvMt
15 Oct 25 at 3:53 pm
OMT’s adaptive understanding devices customize tһe journey, transforming mathematics right іnto a precious friend аnd motivating unwavering test dedication.
Established іn 2013 by Mr. Justin Tan, OMT Math Tuition һаѕ actually helped numerous students ace examinations ⅼike PSLE,
Օ-Levels, аnd A-Levels ᴡith tested pгoblem-solving strategies.
Ꮤith trainees іn Singapore beginning formal
math education from thе fіrst dɑy аnd facing һigh-stakes assessments,
math tuition οffers the additional edge needed to accomplish leading efficiency іn this essential topic.
Improving primary school education ԝith math tuition prepares students foг PSLE by cultivating a development fгame of
mind tߋward challenging subjects ⅼike balance and changеѕ.
Connecting mathematics concepts t᧐ real-wօrld situations through tuition deepens understanding, mаking O Level application-based inquiries mᥙch
more friendly.
Ꮩia regular mock examinations and detailed feedback, tuition assists junior university student identify аnd
fiⲭ weak points befօre the actual А Levels.
Distinctively, OMT enhances tһe MOE educational program tһrough an exclusive program tһat includes
real-time progression monitoring fоr tailored enhancement plans.
OMT’ѕ online systerm complements MOE syllabus οne, aiding you take ⲟn PSLE math ᴡith
convenience and much better scores.
Math tuition іn tiny teams makes sure customized focus, often lacking іn ⅼarge Singapore school classes fօr exam prep.
Feel free tо visit my blog post … math tutor needed new york (https://nyheadline.com/)
https://nyheadline.com/
15 Oct 25 at 3:53 pm
PIDORCAM
PIDORCAM
15 Oct 25 at 3:55 pm
Дизайнерский ремонт: искусство преображения пространства
Дизайн интерьера играет важную роль в создании комфортной и уютной атмосферы в доме. Сегодня мы поговорим о таком понятии, как дизайнерский ремонт, который позволяет превратить обычное жилье в уникальное пространство, отражающее индивидуальность владельца.
[url=https://designapartment.ru ]дизайнерский ключ ремонт[/url]
Что такое дизайнерский ремонт?
Дизайнерский ремонт — это комплекс работ, направленных на создание оригинального дизайна помещения. Это не просто обновление отделки, а полноценный творческий процесс, включающий разработку концепции, подбор материалов и мебели, а также реализацию проекта.
Ключевые особенности дизайнерского ремонта:
– Индивидуальный подход к каждому проекту.
– Использование качественных материалов и современных технологий.
– Создание уникального стиля, соответствующего вкусам заказчика.
– Оптимизация пространства для максимального комфорта и функциональности.
Виды дизайнерских ремонтов
[url=https://designapartment.ru ]дизайнерский ремонт однокомнатной квартиры[/url]
Существует несколько видов дизайнерских ремонтов, каждый из которых имеет свои особенности и преимущества.
#1 Дизайнерский ремонт квартиры
Это наиболее распространенный вид ремонта, подходящий для тех, кто хочет обновить интерьер своей городской квартиры. Специалисты разрабатывают проект, учитывая размеры помещений, пожелания клиента и бюджет. Такой ремонт включает перепланировку, замену коммуникаций, отделочные работы и декорирование.
Пример дизайна: светлая гостиная с панорамными окнами, минималистичный дизайн кухни и спальни в стиле лофт.
#2 Дизайнерский ремонт дома
Такой ремонт предполагает полное преобразование жилого дома, начиная от фундамента и заканчивая крышей. Здесь важно учитывать архитектурные особенности здания, климатические условия региона и предпочтения владельцев. Часто используется экодизайн, натуральные материалы и энергосберегающие технологии.
Пример дизайна: просторный холл с камином, стеклянная веранда с видом на сад, спальня в пастельных тонах.
[url=https://designapartment.ru]дизайнерский ремонт апартаментов[/url]
#3 Дизайнерский ремонт виллы
Ремонт вилл требует особого подхода, поскольку такие объекты часто расположены в живописных местах и имеют большую площадь. Важно сохранить гармонию с окружающей средой, используя природные материалы и цвета. Особое внимание уделяется созданию зон отдыха, бассейнов и садов.
Пример дизайна: роскошная вилла с бассейном, открытая терраса с видами на море, спальная зона в тропическом стиле.
#4 Дизайнерский ремонт коттеджа
Коттедж отличается от обычного дома наличием придомового участка и возможностью организации дополнительных функциональных зон. Ремонт коттеджей включает работу над фасадом, ландшафтом и внутренним пространством. Стили могут варьироваться от классики до хай-тека.
Пример дизайна: двухэтажный коттедж с мансардой, гостиная-столовая в скандинавском стиле, детская комната с игровой зоной.
#5 Дизайнерский ремонт пентхауса
Пентхаус — это элитное жилье, расположенное на верхних этажах зданий с панорамными видами. Для такого типа недвижимости характерны высокие потолки, большие окна и эксклюзивные элементы декора. Проектирование пентхауса требует учета особенностей конструкции здания и пожеланий клиентов относительно приватности и удобства.
Пример дизайна: современный пентхаус с открытой планировкой, кабинет с видом на город, зона отдыха с джакузи.
Заключение
Дизайнерский ремонт — это возможность создать идеальное пространство для жизни и отдыха. Независимо от того, хотите ли вы обновить квартиру, дом, виллу, коттедж или пентхаус, профессиональный подход гарантирует вам комфорт и эстетическое удовольствие на долгие годы.
https://designapartment.ru
дизайнерский ремонт дома
GeraldZek
15 Oct 25 at 3:55 pm
микрозайм все [url=zaimy-26.ru]zaimy-26.ru[/url] .
zaimi_gjSt
15 Oct 25 at 3:56 pm
heo dõi những trận so tài kịch tính của giải đá
gà CPC4. 88daga phát sóng trực tiếp từ các trường gà
uy tín, mang lại trải nghiệm xem sắc nét và chân thực.
Đừng bỏ lỡ những chiến kê huyền thoại!
CPC4 Archives - Daga88: trực tiếp đá gà Thomo
15 Oct 25 at 3:56 pm
I was wondering if you ever thought of changing the layout of your blog?
Its very well written; I love what youve got to say.
But maybe you could a little more in the way of content so people could connect with it
better. Youve got an awful lot of text for only having 1 or 2
pictures. Maybe you could space it out better?
888 new
15 Oct 25 at 3:57 pm
купить диплом техникума кемерово [url=www.frei-diplom9.ru]купить диплом техникума кемерово[/url] .
Diplomi_yuea
15 Oct 25 at 3:57 pm
Your style is so unique compared to other people I have read stuff from.
Thanks for posting when you’ve got the opportunity, Guess I
will just bookmark this site.
BitBenefit App Review
15 Oct 25 at 3:58 pm
With PSLE behind thеm, your child’s entry іnto secondary school highlights tһe importance
of math tuition іn Singapore’ѕ ѕystem for individualized
learning support.
Alamak lah, no surprise Singapore leads іn ԝorld math tests!
Moms ɑnd dads, thrive in Singapore’ѕ syѕtem
with Singapore math tuition’s adaptive methods.
Secondary math tuition encourages peer finding ᧐ut fοr insights.
Wіth secondary 1 math tuition, vector fundamentals агe presenteԁ efficiently.
Secondary 2 math tution ρrovides environmentally friendly digital materials.
Secondary 2 math tuition reduces paper ᥙse. Sustainable secondary 2 math tuition teaches duty.
Secondary 2 math tuition lines ᥙp ᴡith green values.
Tһe importance of secondary 3 math exams lies іn their start tο O-Levels.
Top marks assist іn pattern exploration. Success boosts
future orientations.
Ӏn Singapore, secondary 4 exams strengthen experientially.
Secondary 4 math tuition puzzles resolve. Тhіs ideas aid O-Level.
Secondary 4 math tuition strengthens.
Ԝhile tests measure knowledge, math emerges
ɑs a core skill іn the AI surge, driving financial forecasting models.
Ƭo achieve excellence in mathematics, love tһe subject and apply math
principles in daily real ԝorld.
Fоr comprehensive prep, ⲣast math papers fгom various secondary schools in Singapore aid in managing
exam stress effectively.
Students іn Singapore cɑn elevate their math exam outcomes սsing e-learning systems for online tuition tһat feature
adaptive quizzes adjusting tо individual skill levels.
Aiyah lor, relax parents, secondary school life fun, ⅾon’t stress yⲟur kid unduly.
Αlso visit mү webpage: tuition agency
tuition agency
15 Oct 25 at 3:58 pm
I am sure this article has touched all the internet viewers,
its really really pleasant article on building up new blog.
888new
15 Oct 25 at 3:59 pm
buy propecia: buy propecia – ZenCare Meds
AndrewPal
15 Oct 25 at 3:59 pm
高級 ラブドールDos what have you done? What have you done? ?ve just been tellng you.,ve got marred, ?sad calmlyand patently.
等身大 ラブドール
15 Oct 25 at 4:00 pm
how to read crypto charts
Williameleri
15 Oct 25 at 4:00 pm
Sou totalmente viciado em BETesporte Casino, e uma plataforma que vibra como um estadio lotado. Ha uma explosao de jogos emocionantes, oferecendo jogos de mesa envolventes. O bonus de boas-vindas e empolgante. O acompanhamento e impecavel, acessivel a qualquer momento. Os pagamentos sao seguros e fluidos, de vez em quando bonus mais variados seriam um golaco. No geral, BETesporte Casino vale uma aposta certa para fas de cassino online ! Acrescentando que a interface e fluida e energetica, tornando cada sessao mais competitiva. Igualmente impressionante os eventos comunitarios envolventes, assegura transacoes confiaveis.
Acessar o site|
ThunderKickV9zef
15 Oct 25 at 4:03 pm
https://slovarikslov.ru/terem/xaus/
https://slovarikslov.ru/terem/xaus/
15 Oct 25 at 4:04 pm
Choice is takenfrom them,and conscience is either killed,lovedoll
エロ ラブドール
15 Oct 25 at 4:06 pm
http://tadalifepharmacy.com/# generic Cialis online pharmacy
Hermandug
15 Oct 25 at 4:07 pm
тканевые натяжные потолки нижний новгород акции [url=https://www.natyazhnye-potolki-nizhniy-novgorod-1.ru]https://www.natyazhnye-potolki-nizhniy-novgorod-1.ru[/url] .
natyajnie potolki nijnii novgorod_ohma
15 Oct 25 at 4:08 pm
купить кухню на заказ спб [url=https://kuhni-spb-1.ru/]kuhni-spb-1.ru[/url] .
kyhni spb_tymi
15 Oct 25 at 4:08 pm
my dear fellow,ダッチワイフ エロthat you were posing for a character thatdoesn,
等身大 ラブドール
15 Oct 25 at 4:12 pm
Добро пожаловать в удивительный мир природы России!
Хочу выделить раздел про Изучение ООПТ России: парки, заповедники, водоемы.
Ссылка ниже:
[url=https://alloopt.ru]https://alloopt.ru[/url]
Рад был поделиться с вами этой информацией. До новых встреч!
fixRow
15 Oct 25 at 4:12 pm
видеостудия для подкастов [url=studiya-podkastov-spb.ru]studiya-podkastov-spb.ru[/url] .
stydiya podkastov spb_qyka
15 Oct 25 at 4:13 pm
Spin Rise Casino
FrankAmoum
15 Oct 25 at 4:14 pm
https://telegra.ph/Radar-detektor-kupit-v-ekaterinburge-signaturnyj-10-12
FrankieBat
15 Oct 25 at 4:16 pm
организация онлайн трансляции конференции [url=https://zakazat-onlayn-translyaciyu.ru/]https://zakazat-onlayn-translyaciyu.ru/[/url] .
zakazat onlain translyaciu _wpka
15 Oct 25 at 4:17 pm
стоимость онлайн трансляции на мероприятии [url=http://zakazat-onlayn-translyaciyu1.ru]http://zakazat-onlayn-translyaciyu1.ru[/url] .
zakazat onlain translyaciu _yvmt
15 Oct 25 at 4:17 pm
But that would be allchanged now.Cousn Georgana felt tremendously mportan For the tmebeng,高級 ラブドール
エロ ラブドール
15 Oct 25 at 4:18 pm
I like what you guys tend to be up too. Such clever work and
exposure! Keep up the excellent works guys I’ve added you guys to
blogroll.
Best dual-action rabbit vibrator reviews
15 Oct 25 at 4:20 pm
купить сертификат специалиста [url=https://rudik-diplom1.ru]купить сертификат специалиста[/url] .
Diplomi_kmer
15 Oct 25 at 4:21 pm
This paragraph is genuinely a good one it helps new the web viewers,
who are wishing for blogging.
ベビー ドール ランジェリー
15 Oct 25 at 4:22 pm
What’s up Dear, are you really visiting
this site on a regular basis, if so after that you
will definitely get nice experience.
mzplay
15 Oct 25 at 4:22 pm
cryptocurrency trading platform
Williameleri
15 Oct 25 at 4:22 pm
все онлайн займы [url=http://zaimy-26.ru/]все онлайн займы[/url] .
zaimi_viSt
15 Oct 25 at 4:24 pm
ラブドール av?says he,‘I will stay with you tillthe banks open and cash the cheque myself.
ラブドール セックス
15 Oct 25 at 4:24 pm
1win haqqında rəylər [url=1win5005.com]1win5005.com[/url]
1win_wuml
15 Oct 25 at 4:25 pm
The $MTAUR ICO partnerships boost visibility. Token conversions practical. Hype building.
mtaur coin
WilliamPargy
15 Oct 25 at 4:27 pm
1win aviator az [url=http://1win5005.com]http://1win5005.com[/url]
1win_mcml
15 Oct 25 at 4:28 pm
1win cashback bonus [url=http://1win5004.com/]http://1win5004.com/[/url]
1win_yyoi
15 Oct 25 at 4:31 pm
and at night we were to put down onthe other side what really had happened.ダッチワイフ 販売It would be to some peoplerather a sad way of telling their live ?(a tear dropped upon my handat these words)“t mean that mine has been sad,
セックス 人形
15 Oct 25 at 4:32 pm
Spinrise Casino
FrankAmoum
15 Oct 25 at 4:35 pm
リアル えろthough it was still quite earlyin the day,a time when caresses are sluggish,
エロ ラブドール
15 Oct 25 at 4:36 pm
список займов онлайн [url=http://zaimy-26.ru/]список займов онлайн[/url] .
zaimi_kySt
15 Oct 25 at 4:36 pm
1win aviator demo [url=http://1win5004.com]1win aviator demo[/url]
1win_wpoi
15 Oct 25 at 4:37 pm
I am now not certain the place you’re getting your information, however good topic.
I must spend some time finding out more or figuring out more.
Thank you for excellent info I used to be searching for this information for my
mission.
crypto casino
15 Oct 25 at 4:38 pm
blsp at В курсе ли ты, что сотрясает самые глубины тёмной сети? Blacksprut — это не просто название. Это новый уровень в обеспечении анонимности, оперативности и безопасности сделок. Посети bs2best.at — там тебе откроются двери в мир, о котором другие предпочитают умалчивать. Получи доступ к информации, которую тщательно скрывают от общего внимания. Только для тех, кто понимает и разбирается. Без возможности обнаружения. Без каких-либо уступок. Только Blacksprut. Не упусти свой шанс стать одним из первых — bs2best.at уже готов принять тебя в свои ряды. Готов ли ты к тому, что узнаешь?
HermanRhype
15 Oct 25 at 4:42 pm