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=natyazhnye-potolki-samara-2.ru]тканевый натяжной потолок самара[/url] .
natyajnie potolki samara_djPi
15 Oct 25 at 5:15 am
Way cool! Some very valid points! I appreciate you penning this post plus the rest of the website
is also very good.
Yupoo Dior
15 Oct 25 at 5:15 am
Since the admin of this website is working, no hesitation very quickly it will
be famous, due to its quality contents.
my link
15 Oct 25 at 5:19 am
купить диплом в сочи [url=rudik-diplom6.ru]купить диплом в сочи[/url] .
Diplomi_adKr
15 Oct 25 at 5:20 am
Сеть пансионатов «Друзья» — это когда о близком заботятся так же внимательно, как дома, но с профессиональной поддержкой 24/7. Круглосуточный уход, контроль приёма лекарств, ежедневные замеры, доступная среда, пятиразовое питание по меню диетолога и насыщенный досуг от прогулок до мастер-классов. На выбор — семь пансионатов вокруг Москвы и гибкие тарифы: базовая стоимость уже включает медуход, питание и развлечения. Посмотрите адреса, условия и оставьте заявку на консультацию на https://friends-pansionat.ru/ — здесь помогают жить полноценно и спокойно.
xavaqthciC
15 Oct 25 at 5:20 am
masturbate
Brentsek
15 Oct 25 at 5:20 am
Hello There. I found your blog using msn. This is a really well written article.
I will be sure to bookmark it and come back to read more of your useful information. Thanks for the post.
I will definitely return.
Siding Replacement Washington
15 Oct 25 at 5:21 am
https://brandies.bizlisting.cloud/code-promo-1xbet-pari-gratuit-bonus-130e/
hpqzqst
15 Oct 25 at 5:22 am
Hey hey, composed pom pі ρi, mathematics
гemains among from thе hiɡhest disciplines at Junior College,
establishing groundwork tо Ꭺ-Level advanced math.
Ӏn additіоn to school facilities, focus սpon math in oгder to avoid frequent erors ⅼike inattentive blunders durіng exams.
Parents, fearful ߋf losing style ߋn lah, strong primary math
гesults f᧐r superior scientific comprehension аnd construction aspirations.
Eunoia Junior College represents contemporary development іn education, ѡith itѕ hіgh-rise school integrating community spaces f᧐r collective knowing and growth.
Tһe college’s focus on beautiful thinking promotes
intellectual іnterest ɑnd goodwill, supported by dynamic programs іn arts,
sciences, and leadership. Cutting edge facilities,
consisting ⲟf performing arts рlaces, enable students to explore passions ɑnd
establish skills holistically. Partnerships ѡith esteemed organizations offer enhancing
opportunities fօr research study and global direct exposure.
Students emerge ɑs thoughtful leaders, ready tߋ contribute favorably tօ a diverse woгld.
Ѕt. Andrew’s Junior College accepts Anglican worths
tо promote holistic development, cultivating principled people ᴡith robust
character traits thrοugh a blend оf spiritual assistance,
academic pursuit, аnd community involvement in a warm ɑnd inclusive environment.
The college’ѕ contemporary facilities, including interactive classrooms,
sports complexes, аnd imaginative arts studios, facilitate excellence tһroughout
scholastic disciplines, sports programs tһat emphasize fitness and
reasonable play, and artistic undertakings tһɑt encourage ѕеlf-expression and innovation. Community service initiatives,
ѕuch ɑs volunteer partnerships ԝith regional organizations
and outreach tasks, instill empathy, social duty, ɑnd a sense of function, improving
students’ academic journeys. Α diverse variety
οf co-curricular activities, fгom dispute societies to musical ensembles,
promotes teamwork, leadership skills, ɑnd personal discovery,
permitting every trainee to shine in their chosen аreas.
Alumni of St. Andrew’s Junior College regularly emerge as ethical, durable leaders ѡho make meaningful contributions
to society, ѕhowing the institution’ѕ profound impact on developing weⅼl-rounded, vɑlue-drivenindividuals.
Oh dear, lacking robust mathematics аt Junior College, no matter prestigious establishment kids mіght stumble in high school calculations, tһսs cultivate іt promptⅼy leh.
Hey hey, Singapore folks, maths proves рerhaps the mоst essential primary subject, fostering creativity
fоr problem-solving for innovative jobs.
Օh man, regardless tһough establishment proves fancy,
maths serves ɑs the critical subject foг cultivates assurance witһ numbеrs.
Beѕides fгom school amenities, concentrate оn mathematics іn ordеr to stop frequenjt errors ѕuch as inattentive mistakes ԁuring exams.
Parents, competitive style engaged lah, robust primary mathematics гesults
foг better scientific grasp pⅼᥙѕ tech dreams.
Wow, math serves ass tһe foundation stone in primary education, aiding kids іn geometric thinking tߋ building careers.
Ⅾon’t relax іn JC Yeаr 1; A-levels build on earⅼy foundations.
Eh eh, steady pom рi pi, maths remаins amօng from the highest subjects ɗuring
Junior College, establishing foundation іn A-Level
calculus.
Feel free to visit my web-site: junior colleges
junior colleges
15 Oct 25 at 5:22 am
купить диплом техникума в нальчике [url=https://www.frei-diplom11.ru]купить диплом техникума в нальчике[/url] .
Diplomi_wjsa
15 Oct 25 at 5:24 am
Процедура всегда начинается с личной консультации. Врач-нарколог выясняет анамнез, оценивает физическое и психическое состояние, рассказывает о возможных методиках и противопоказаниях. После выбора оптимального метода пациенту объясняются все нюансы, отвечают на вопросы, выдают письменные рекомендации по поведению в период действия кодировки.
Получить дополнительную информацию – [url=https://kodirovanie-ot-alkogolizma-kolomna6.ru/]metody-kodirovaniya-ot-alkogolizma-cena[/url]
Rodneybeany
15 Oct 25 at 5:25 am
https://telegra.ph/Teplovizionnyj-monokulyar-arkon-ovis-kupit-10-12
RonaldZer
15 Oct 25 at 5:25 am
купить диплом в донском [url=http://rudik-diplom9.ru/]http://rudik-diplom9.ru/[/url] .
Diplomi_urei
15 Oct 25 at 5:27 am
купить диплом в первоуральске [url=http://rudik-diplom7.ru/]http://rudik-diplom7.ru/[/url] .
Diplomi_wuPl
15 Oct 25 at 5:27 am
мед колледж купить диплом [url=http://frei-diplom9.ru/]мед колледж купить диплом[/url] .
Diplomi_xlea
15 Oct 25 at 5:27 am
https://www.imdb.com/list/ls4155690279/
loaznwm
15 Oct 25 at 5:29 am
где купить диплом с занесением реестр [url=www.frei-diplom1.ru]где купить диплом с занесением реестр[/url] .
Diplomi_skOi
15 Oct 25 at 5:29 am
купить диплом менеджера [url=https://rudik-diplom6.ru]купить диплом менеджера[/url] .
Diplomi_hbKr
15 Oct 25 at 5:30 am
Хотите узнать больше о природе нашей страны? Присоединяйтесь к обсуждению.
Для тех, кто ищет информацию по теме “Изучение ООПТ России: парки, заповедники, водоемы”, нашел много полезного.
Смотрите сами:
[url=https://alloopt.ru]https://alloopt.ru[/url]
Рад был поделиться с вами этой информацией. До новых встреч!
fixRow
15 Oct 25 at 5:30 am
Minotaurus token’s DAO governance empowers users. Presale’s multi-crypto support widens access. Battling obstacles feels epic.
minotaurus coin
WilliamPargy
15 Oct 25 at 5:30 am
купить диплом занесением в реестр [url=http://frei-diplom2.ru]купить диплом занесением в реестр[/url] .
Diplomi_lyEa
15 Oct 25 at 5:33 am
купить диплом с занесением в реестр челябинск [url=https://www.frei-diplom3.ru]купить диплом с занесением в реестр челябинск[/url] .
Diplomi_bvKt
15 Oct 25 at 5:34 am
можно ли купить диплом медсестры [url=https://frei-diplom13.ru]можно ли купить диплом медсестры[/url] .
Diplomi_pgkt
15 Oct 25 at 5:34 am
Новинки фильмов и сериалов торрент Фильмы 2023 скачать торрент Переживите заново эмоции от просмотра лучших фильмов 2023 года! На нашем сайте вы найдете широкий выбор кинокартин, которые покорили сердца зрителей в прошлом году. Мы предлагаем скачать фильмы 2023 торрент в высоком качестве, чтобы вы могли наслаждаться просмотром любимых фильмов в отличном качестве. У нас вы найдете фильмы различных жанров: от захватывающих экшенов и фантастических саг до трогательных мелодрам и комедийных историй. Наша коллекция постоянно пополняется, поэтому вы всегда сможете найти что-то интересное для себя. Благодаря удобной системе поиска и фильтрации вы легко сможете найти нужный фильм по названию, жанру, году выпуска, рейтингу и другим критериям. Скачивайте фильмы 2023 торрент быстро и безопасно с нашего сайта! Мы гарантируем высокое качество файлов и отсутствие вирусов. Наслаждайтесь просмотром лучших фильмов 2023 года в любое время и в любом месте!
Raymondcoedo
15 Oct 25 at 5:37 am
купить диплом в сосновом бору [url=www.rudik-diplom13.ru/]www.rudik-diplom13.ru/[/url] .
Diplomi_oron
15 Oct 25 at 5:38 am
легально купить диплом [url=http://www.frei-diplom1.ru]легально купить диплом[/url] .
Diplomi_pgOi
15 Oct 25 at 5:39 am
4M Dental Implant Center
3918 ᒪong Beach Blvdd #200, Ꮮong Beach,
ϹA 90807, United Ѕtates
15622422075
prosthodontics (https://raindrop.io/)
https://raindrop.io/
15 Oct 25 at 5:39 am
купить диплом в невинномысске [url=http://rudik-diplom7.ru]купить диплом в невинномысске[/url] .
Diplomi_thPl
15 Oct 25 at 5:41 am
Nuru Massage Bangkok | Premium Erotic massage Experience.
Discover authentic Japanese Nuru massage in Bangkok’s best parlors like Hiso.
Full body-to-body relaxation with a happy ending. Book your sensual
journey now.
sensual body massage
15 Oct 25 at 5:41 am
горный техникум диплом купить [url=www.frei-diplom9.ru/]горный техникум диплом купить[/url] .
Diplomi_tpea
15 Oct 25 at 5:41 am
The buzz on Minotaurus presale is real, surpassing milestones fast. $MTAUR’s tokenomics prioritize sustainability over quick flips. Game’s whimsical elements shine.
minotaurus coin
WilliamPargy
15 Oct 25 at 5:45 am
купить диплом в калуге [url=rudik-diplom2.ru]купить диплом в калуге[/url] .
Diplomi_kwpi
15 Oct 25 at 5:45 am
buy viagra [url=http://britpharmonline.com/#]order ED pills online UK[/url] buy viagra online
Jameshoasy
15 Oct 25 at 5:45 am
купить диплом проведенный [url=http://www.frei-diplom1.ru]купить диплом проведенный[/url] .
Diplomi_huOi
15 Oct 25 at 5:45 am
Лазерные станки https://raymark.ru для резки металла в Москве. 20 лет на рынке, выгодная цена, скидка 5% при заявке с сайта + обучение
raymark-453
15 Oct 25 at 5:46 am
потолочник [url=natyazhnye-potolki-samara-2.ru]потолочник[/url] .
natyajnie potolki samara_jcPi
15 Oct 25 at 5:46 am
диплом высшего образования с занесением в реестр купить [url=https://www.frei-diplom2.ru]диплом высшего образования с занесением в реестр купить[/url] .
Diplomi_xiEa
15 Oct 25 at 5:47 am
диплом проведенный купить [url=www.frei-diplom3.ru/]диплом проведенный купить[/url] .
Diplomi_qaKt
15 Oct 25 at 5:47 am
HOME CLIMAT https://homeclimat36.ru кондиционеры и сплит системы в Воронеже. Скидка на монтаж от 3000 рублей! При покупке сплит-системы.
homeclimat36-521
15 Oct 25 at 5:48 am
можно купить диплом медсестры [url=http://www.frei-diplom13.ru]можно купить диплом медсестры[/url] .
Diplomi_xlkt
15 Oct 25 at 5:48 am
где купить диплом образование [url=www.rudik-diplom9.ru]где купить диплом образование[/url] .
Diplomi_zlei
15 Oct 25 at 5:48 am
https://www.ozbargain.com.au/user/552285
Nathanhip
15 Oct 25 at 5:51 am
Если вы ищете место, где новые и любимые сериалы собраны в одном каталоге, обратите внимание на https://seasonvar.one — здесь быстро появляются свежие серии с удобной навигацией по жанрам, алфавиту и обновлениям. Вы оцените продолжение с места остановки и ленту обновлений по датам — ориентироваться легко. Минималистичный интерфейс, мгновенно доступное HD и аккуратно подобранная русская озвучка. Отличный выбор для занятых зрителей, которые смотрят в ознакомительных целях и ценят удобство.
kafawcaurn
15 Oct 25 at 5:51 am
https://www.behance.net/otellotravel/info
Nathanhip
15 Oct 25 at 5:53 am
купить аттестат школы [url=www.rudik-diplom2.ru/]купить аттестат школы[/url] .
Diplomi_vhpi
15 Oct 25 at 5:54 am
диплом техникума купить [url=http://www.frei-diplom9.ru]диплом техникума купить[/url] .
Diplomi_csea
15 Oct 25 at 5:54 am
купить диплом в чебоксарах [url=http://rudik-diplom7.ru/]купить диплом в чебоксарах[/url] .
Diplomi_uaPl
15 Oct 25 at 5:55 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.
mtaur token
WilliamPargy
15 Oct 25 at 5:55 am
https://telegra.ph/Kupit-kryshku-obektiva-na-ti-teplovizor-pard-10-12-5
RonaldZer
15 Oct 25 at 5:57 am
купить диплом средне техническое [url=https://rudik-diplom10.ru/]купить диплом средне техническое[/url] .
Diplomi_psSa
15 Oct 25 at 5:59 am