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://vyvod-iz-zapoya-v-stacionare21.ru/]стационар вывод из запоя нижний новгород[/url]
CharlesElage
8 Oct 25 at 4:53 am
наркология москва [url=https://narkologicheskaya-klinika-19.ru/]https://narkologicheskaya-klinika-19.ru/[/url] .
narkologicheskaya klinika _iwmi
8 Oct 25 at 4:55 am
Woah! I’m really digging the template/theme of this website.
It’s simple, yet effective. A lot of times it’s tough to get that
“perfect balance” between usability and appearance.
I must say you’ve done a superb job with this.
Also, the blog loads super quick for me on Opera.
Outstanding Blog!
صفحات پیلار چیست
8 Oct 25 at 4:57 am
наркологическая клиника [url=http://www.narkologicheskaya-klinika-19.ru]http://www.narkologicheskaya-klinika-19.ru[/url] .
narkologicheskaya klinika _lhmi
8 Oct 25 at 4:58 am
спортивный прогноз на сегодня [url=https://prognozy-ot-professionalov5.ru/]спортивный прогноз на сегодня[/url] .
prognozi ot professionalov_lzSt
8 Oct 25 at 4:59 am
наркологические клиники [url=http://www.narkologicheskaya-klinika-19.ru]http://www.narkologicheskaya-klinika-19.ru[/url] .
narkologicheskaya klinika _evmi
8 Oct 25 at 5:01 am
Kaizenaire.сom aggregates Singapore’ѕ hottest deals,
developing іtself as the leading promotions website.
Singapore’ѕ status aѕ a shopping capital reverberates ԝith Singaporeans,
that аlways focus on promotions in thеiг ԛuest for lots.
Checking out books аt comfy libraries supplies а calm getaway fоr bookish Singaporeans, ɑnd remember tօ stay upgraded оn Singapore’s newest promotions ɑnd
shopping deals.
Wrkshop HHFZ creates vibrant, artistic fashion tһings, loved Ƅу imaginative Singaporeans for theіr ⲟne-ߋf-a-kind
patterns and expressive layouts.
Ϲomo Hotels offеrs boutique friendliness ɑnd eating
leh, valued Ƅy Singaporeans for thеir sophisticated гemains and cooking delights ⲟne.
Swee Choon Tim Sum pleases late-night cravings wіth fit tо
bе tied delights, enjoyed fоr 24-һour service
and timeless Cantonese tastes.
Eh, clever Singaporeans mah, visit Kaizenaire.сom сonstantly lah.
My web page: singapore promo
singapore promo
8 Oct 25 at 5:03 am
В Екатеринбурге «Stop-Alko» предлагает вывод из запоя на дому круглосуточно — консультация, выезд медика, капельница и медикаменты при необходимости.
Подробнее тут – [url=https://vyvod-iz-zapoya-ekaterinburg26.ru/]вывод из запоя на дому круглосуточно екатеринбург[/url]
Briangex
8 Oct 25 at 5:03 am
прогнозы на спорт с аналитикой [url=http://prognozy-ot-professionalov5.ru/]http://prognozy-ot-professionalov5.ru/[/url] .
prognozi ot professionalov_spSt
8 Oct 25 at 5:05 am
спорт новости [url=www.sport-novosti-2.ru]спорт новости[/url] .
sport novosti_hamn
8 Oct 25 at 5:07 am
The $MTAUR token seems like a solid pick for anyone into casual gaming with crypto twists. Navigating mazes as a minotaur while earning in-game currency sounds addictive and rewarding. With the presale offering 80% off, it’s hard not to jump in early.
minotaurus coin
WilliamPargy
8 Oct 25 at 5:07 am
Снятие интоксикации, восстановление организма и наблюдение — так проходит вывод из запоя в стационаре «Частный Медик 24».
Узнать больше – [url=https://vyvod-iz-zapoya-v-stacionare23.ru/]вывод из запоя в стационаре клиника нижний новгород[/url]
Jeffreyneink
8 Oct 25 at 5:07 am
прогнозы на спорт от экспертов [url=prognozy-ot-professionalov5.ru]prognozy-ot-professionalov5.ru[/url] .
prognozi ot professionalov_odSt
8 Oct 25 at 5:08 am
прогнозы на спорт от экспертов [url=https://prognozy-ot-professionalov4.ru/]https://prognozy-ot-professionalov4.ru/[/url] .
prognozi ot professionalov_gpOr
8 Oct 25 at 5:08 am
лечение зависимостей в москве [url=http://narkologicheskaya-klinika-19.ru/]http://narkologicheskaya-klinika-19.ru/[/url] .
narkologicheskaya klinika _hzmi
8 Oct 25 at 5:12 am
спортивные новости сегодня [url=https://sportivnye-novosti-2.ru/]спортивные новости сегодня[/url] .
sportivnie novosti_vsma
8 Oct 25 at 5:13 am
Kenvox
1701 E Edinger Ave
Santa Ana, ᏟA 92705, United States
16572319025
Best silicone fabrication processes
Best silicone fabrication processes
8 Oct 25 at 5:13 am
You’ve made some really good points there.
I looked on the internet to find out more about the issue and
found most people will go along with your views on this
web site.
Flectorio Inmediato Opiniones
8 Oct 25 at 5:18 am
whollywoodhalloween – I didn’t expect it to be this fun to explore online.
Orlando Way
8 Oct 25 at 5:18 am
новости олимпиады [url=https://www.sportivnye-novosti-2.ru]новости олимпиады[/url] .
sportivnie novosti_bbma
8 Oct 25 at 5:19 am
реабилитация зависимых [url=www.narkologicheskaya-klinika-19.ru]www.narkologicheskaya-klinika-19.ru[/url] .
narkologicheskaya klinika _tpmi
8 Oct 25 at 5:20 am
generic ivermectin online pharmacy: Stromectol ivermectin tablets for humans USA – trusted Stromectol source online
Morrisluh
8 Oct 25 at 5:21 am
спортивные события [url=http://www.sport-novosti-2.ru]http://www.sport-novosti-2.ru[/url] .
sport novosti_vhmn
8 Oct 25 at 5:21 am
We offer expert support for your Singapore Employment Pass
application, helping professionals secure work authorization quickly and
smoothly.
Employment Pass Singapore
8 Oct 25 at 5:21 am
В Екатеринбурге «Похмельная Служба» проводит вывод из запоя анонимно и безопасно, с применением современных препаратов.
Получить дополнительную информацию – [url=https://vyvod-iz-zapoya-ekaterinburg26.ru/]срочный вывод из запоя в екатеринбурге[/url]
Briangex
8 Oct 25 at 5:22 am
проходимые прогнозы на спорт [url=https://prognozy-ot-professionalov5.ru/]https://prognozy-ot-professionalov5.ru/[/url] .
prognozi ot professionalov_idSt
8 Oct 25 at 5:22 am
https://getrejoin.com/ru/question/chto-takoe-veb-analitika-1525588.html
Thomasbip
8 Oct 25 at 5:23 am
вывод из запоя цены на дому москва [url=http://www.vyvod-iz-zapoya-9.ru]http://www.vyvod-iz-zapoya-9.ru[/url] .
vivod iz zapoya_eqEl
8 Oct 25 at 5:23 am
LDV-Case — дизайн-ателье премиальных чехлов из натуральной кожи для популярных моделей смартфонов. Ручная работа, редкие фактуры (страус, змея, крокодил, нога страуса), плотная посадка без зазоров и долговечность, подтверждённая отзывами. Возможен индивидуальный заказ, быстрая доставка и консультации: цены честные, выбор — широкий. Загляните в каталог готовых изделий на https://ldv-case.shop/ и создайте аксессуар, который подчеркнёт ваш стиль каждый день.
qerohoPielf
8 Oct 25 at 5:24 am
наркологические клиники москвы [url=http://narkologicheskaya-klinika-19.ru/]http://narkologicheskaya-klinika-19.ru/[/url] .
narkologicheskaya klinika _fomi
8 Oct 25 at 5:24 am
больница наркологическая [url=https://narkologicheskaya-klinika-19.ru/]https://narkologicheskaya-klinika-19.ru/[/url] .
narkologicheskaya klinika _pzmi
8 Oct 25 at 5:27 am
order Stromectol discreet shipping USA [url=http://medivermonline.com/#]order Stromectol discreet shipping USA[/url] Mediverm Online
Michaelriz
8 Oct 25 at 5:27 am
спорт новости [url=www.sport-novosti-2.ru]спорт новости[/url] .
sport novosti_fhmn
8 Oct 25 at 5:27 am
В больничных условиях «Частного Медика 24» врачи контролируют давление, сердце и функции жизненно важных органов при выводе из запоя.
Подробнее можно узнать тут – [url=https://vyvod-iz-zapoya-v-stacionare-samara24.ru/]вывод из запоя в стационаре самара[/url]
Jamessor
8 Oct 25 at 5:30 am
how to order Cialis online legally: how to order Cialis online legally – EverLastRx
WillieRuivy
8 Oct 25 at 5:30 am
Thanks in favor of sharing such a good opinion, paragraph is good, thats why i have read it
entirely
hatimanis88
8 Oct 25 at 5:33 am
новости футбола [url=https://sport-novosti-2.ru/]новости футбола[/url] .
sport novosti_eemn
8 Oct 25 at 5:33 am
наркологические услуги [url=www.narkologicheskaya-klinika-19.ru]www.narkologicheskaya-klinika-19.ru[/url] .
narkologicheskaya klinika _wemi
8 Oct 25 at 5:35 am
There’s definately a great deal to learn about this
subject. I love all of the points you made.
독학기숙학원
8 Oct 25 at 5:35 am
новости чемпионатов [url=https://sportivnye-novosti-2.ru]новости чемпионатов[/url] .
sportivnie novosti_ltma
8 Oct 25 at 5:36 am
bestchangeru.com — Надежный Обменник Валют Онлайн
¦ Что такое BestChange?
[url=https://bestchangeru.com/]сайт bestchange[/url]
bestchangeru.com является одним из наиболее популярных сервисов мониторинга обменников электронных валют в русскоязычном сегменте сети Интернет. Платформа была создана для упрощения процесса выбора надежного онлайн-обмена валюты среди множества предложений.
¦ Основные преимущества BestChange:
https://bestchangeru.com/
bestchange
– Мониторинг лучших курсов: Лучшие курсы покупки и продажи криптовалют и электронных денег автоматически обновляются в режиме реального времени.
– Автоматическое сравнение: Удобный интерфейс позволяет мгновенно сравнить десятки предложений и выбрать оптимальное.
– Обзор отзывов пользователей: Пользователи оставляют отзывы и оценки, помогающие другим пользователям принять решение.
– Отсутствие скрытых комиссий: Информация о комиссиях отображается прозрачно и открыто.
¦ Как работает BestChange?
Пользователь вводит необходимые данные: валюту, которую хочет обменять, и желаемую сумму. После этого сервис генерирует список надежных обменных пунктов с лучшими условиями обмена.
Пример: Вы хотите обменять Bitcoin на рубли. Заходите на сайт bestchangeru.com, выбираете направление обмена («Bitcoin > Рубли»), вводите сумму и получаете таблицу проверенных обменных пунктов с наилучшими курсами.
¦ Почему выбирают BestChange?
1. Безопасность. Все обменники проходят строгую проверку перед добавлением в базу сервиса.
2. Удобство пользования. Простота интерфейса позволяет быстро находить нужную информацию даже новичкам.
3. Постоянное обновление базы данных. Курсы и условия регулярно проверяются и обновляются, обеспечивая актуальность информации.
4. Многоязычность. Помимо русского, доступна версия сайта на английском и украинском языках.
Таким образом, bestchangeru.com становится незаменимым помощником в мире цифровых финансов, позволяя легко и безопасно совершать операции обмена валют. Если вам нужен надежный и удобный способ обмена криптовалюты и электронных денег, обязательно обратите внимание на этот ресурс.
AlbertSus
8 Oct 25 at 5:37 am
ukrainianvictoryisthebestaward – Might attract attention globally, especially with strong storytelling.
Jasper Kochen
8 Oct 25 at 5:38 am
Hi! I know this is kinda off topic but I was wondering which blog
platform are you using for this website? I’m getting sick and tired of
Wordpress because I’ve had issues with hackers and I’m looking at options for another platform.
I would be great if you could point me in the direction of a good platform.
noteworthy
8 Oct 25 at 5:42 am
наркология лечение [url=https://www.narkologicheskaya-klinika-19.ru]https://www.narkologicheskaya-klinika-19.ru[/url] .
narkologicheskaya klinika _ismi
8 Oct 25 at 5:44 am
whollywoodhalloween – Absolutely loved the creative ideas shared, everything’s well organized and detailed.
Lecia Saade
8 Oct 25 at 5:45 am
Профессиональные велосипеды для шоссе и гор
kraken онион kraken онион тор кракен онион
RichardPep
8 Oct 25 at 5:45 am
наркология в москве [url=https://narkologicheskaya-klinika-19.ru/]narkologicheskaya-klinika-19.ru[/url] .
narkologicheskaya klinika _bomi
8 Oct 25 at 5:47 am
спорт 24 часа [url=https://sportivnye-novosti-2.ru/]спорт 24 часа[/url] .
sportivnie novosti_apma
8 Oct 25 at 5:49 am
Ich bin begeistert von Snatch Casino, es ist eine dynamische Erfahrung. Das Spielangebot ist beeindruckend, mit immersiven Live-Sitzungen. Die Agenten sind super reaktionsschnell, mit tadellosem Follow-up. Die Zahlungen sind flussig und sicher, manchmal die Angebote konnten gro?zugiger sein. Global Snatch Casino ist ein Must fur Spieler fur Online-Wetten-Enthusiasten ! Beachten Sie auch die Oberflache ist flussig und modern, fugt Komfort zum Spiel hinzu.
HeistMasterH8zef
8 Oct 25 at 5:53 am
Excellent post. I ɑbsolutely аppreciate thіs website.
Stick ѡith it!
Нere іs my web blog math tuition
math tuition
8 Oct 25 at 5:53 am