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=poverkhnost.tv/forum/profile.php?id=23591]poverkhnost.tv/forum/profile.php?id=23591[/url] .
Priobresti diplom ob obrazovanii!_uikt
10 Sep 25 at 8:51 am
где купить диплом с реестром [url=www.arus-diplom34.ru/]где купить диплом с реестром[/url] .
Diplomi_vner
10 Sep 25 at 8:52 am
авиатор 1win играть [url=www.aviator-igra-3.ru/]авиатор 1win играть[/url] .
aviator igra_tmmi
10 Sep 25 at 8:53 am
у меня все без подогрева растворилось
https://rant.li/taaaciidau/lirika-kupit-irkutsk
Первый раз РІРёР¶Сѓ такое СЃ РњРќ. РћС‚ РґСЂСѓРіРёС… селлеров РІСЃРµ было РЅРѕСЂРј СЃ растворимостью. Растворяющийся полностью пер чуть посильнее…
BrianNeins
10 Sep 25 at 8:54 am
aviator money [url=www.aviator-igra-2.ru]www.aviator-igra-2.ru[/url] .
aviator igra_yuol
10 Sep 25 at 8:54 am
I am really impressed with your writing skills as well as with the
layout on your weblog. Is this a paid theme or did you customize it yourself?
Anyway keep up the excellent quality writing, it’s
rare to see a nice blog like this one today.
mv66.com
10 Sep 25 at 8:54 am
Ich bin suchtig nach PlayJango Casino, es ist ein Online-Casino, das wie ein Wirbelsturm tobt. Die Auswahl im Casino ist ein echtes Spektakel, mit Casino-Spielen, die fur Kryptowahrungen optimiert sind. Die Casino-Mitarbeiter sind schnell wie ein Blitzstrahl, ist per Chat oder E-Mail erreichbar. Casino-Gewinne kommen wie ein Komet, ab und zu mehr Freispiele im Casino waren ein Volltreffer. Zusammengefasst ist PlayJango Casino eine Casino-Erfahrung, die wie ein Regenbogen glitzert fur Fans von Online-Casinos! Nebenbei das Casino-Design ist ein optisches Spektakel, Lust macht, immer wieder ins Casino zuruckzukehren.
playjango deposit bonus code|
fizzypanda4zef
10 Sep 25 at 8:56 am
Публикация приглашает вас исследовать неизведанное — от древних тайн до современных достижений науки. Вы узнаете, как случайные находки превращались в революции, а смелые мысли — в новые эры человеческого прогресса.
Нажмите, чтобы узнать больше – https://laborsphere.com/blog
LouisMuS
10 Sep 25 at 8:57 am
BluePill UK http://meditrustuk.com/# trusted online pharmacy ivermectin UK
StuartDop
10 Sep 25 at 8:59 am
wonderful publish, very informative. I wonder why the opposite experts of this sector
do not realize this. You should continue your writing. I am confident, you have a great readers’ base already!
dewascatter link alternatif
10 Sep 25 at 8:59 am
Great goods from you, man. I have understand your stuff previous to and you
are just extremely magnificent. I really like what you’ve
acquired here, certainly like what you’re saying and the way in which you say it.
You make it enjoyable and you still take care of to keep
it sensible. I can’t wait to read much more from you. This is really a
great site.
tải phim mưa đỏ
10 Sep 25 at 8:59 am
always i used to read smaller content which as well clear their motive, and that is also happening with this
paragraph which I am reading here.
home addition contractors
10 Sep 25 at 8:59 am
диплом бакалавра купить стоимость [url=https://educ-ua2.ru]диплом бакалавра купить стоимость[/url] .
Diplomi_oaOt
10 Sep 25 at 8:59 am
диплом занесен в реестр купить [url=http://www.educ-ua15.ru]диплом занесен в реестр купить[/url] .
Diplomi_xbmi
10 Sep 25 at 9:01 am
Unblocked Games Dive into a universe of Unblocked Games, where classic titles meet modern favorites, ensuring there’s always a new adventure waiting around the corner.
MichaelJaf
10 Sep 25 at 9:01 am
Этот обзорный материал предоставляет информационно насыщенные данные, касающиеся актуальных тем. Мы стремимся сделать информацию доступной и структурированной, чтобы читатели могли легко ориентироваться в наших выводах. Познайте новое с нашим обзором!
Изучить материалы по теме – https://changingbankstatements.com/credit-card-installments
Caseyfuh
10 Sep 25 at 9:05 am
Купить диплом колледжа в Днепр [url=https://educ-ua9.ru/]Купить диплом колледжа в Днепр[/url] .
Diplomi_lbpr
10 Sep 25 at 9:05 am
диплом автотранспортного техникума купить в [url=https://educ-ua6.ru/]https://educ-ua6.ru/[/url] .
Diplomi_oxMl
10 Sep 25 at 9:05 am
Hello, all is going sound here and ofcourse every one is sharing facts, that’s truly excellent, keep up writing.
VSbet
10 Sep 25 at 9:05 am
cialis online UK no prescription: confidential delivery cialis UK – cialis online UK no prescription
Jamesmit
10 Sep 25 at 9:05 am
Эта обзорная заметка содержит ключевые моменты и факты по актуальным вопросам. Она поможет читателям быстро ориентироваться в теме и узнать о самых важных аспектах сегодня. Получите краткий курс по современной информации и оставайтесь в курсе событий!
Заходи — там интересно – https://kalemagency.com/mehmetd-2
RobertCag
10 Sep 25 at 9:07 am
Ищете, где срочно сделать санитарную книжку за один день без толкучки и проблем? На сайте [url=https://medraskhodka.ru/]https://medraskhodka.ru/[/url] можно сделать или продлить медкнижку в течение дня: с результатами обследований и заключением терапевта — даже без визита. Услуга актуальна для специалистов пищевой промышленности, ЖКХ и компаний, где требуются профосмотры и допуск. Документы готовятся максимально быстро, а стоимость честная и понятная (от 1 600 ?, обновление с 1 300 ?). Смотрите детали — медкнижка в день, заказ через интернет, без очередей.
Spravkiwrq
10 Sep 25 at 9:07 am
Fantastic website. Plenty of helpful info here. I am sending it to a few friends
ans also sharing in delicious. And obviously, thanks on your effort!
Feel free to surf to my web-site … 인계동하이퍼블릭
인계동하이퍼블릭
10 Sep 25 at 9:08 am
Great goods from you, man. I have keep in mind your stuff prior
to and you’re simply too magnificent. I really like what you’ve bought here, really like what you are stating and the way in which during which you assert
it. You are making it entertaining and you continue to
take care of to keep it smart. I cant wait to learn much more
from you. This is actually a tremendous website.
Alto Bitrow
10 Sep 25 at 9:08 am
Je trouve absolument enivrant PokerStars Casino, c’est un casino en ligne qui brille comme une etoile polaire. La selection du casino est une constellation de delices, avec des machines a sous de casino modernes et envoutantes. Le support du casino est disponible 24/7, repondant en un eclair strategique. Les paiements du casino sont securises et fluides, cependant plus de tours gratuits au casino ce serait un full house. Pour resumer, PokerStars Casino promet un divertissement de casino strategique pour les joueurs qui aiment parier avec flair au casino ! Par ailleurs la navigation du casino est intuitive comme une strategie gagnante, facilite une experience de casino strategique.
pokerstars maintenance today|
zestysquid7zef
10 Sep 25 at 9:10 am
aviator game promo code [url=https://aviator-igra-3.ru]https://aviator-igra-3.ru[/url] .
aviator igra_iami
10 Sep 25 at 9:10 am
продам лошадь Хотите купить коня для души или спорта? Мы предлагаем широкий выбор коней различных пород и возрастов. Наши консультанты помогут вам подобрать идеального коня, соответствующего вашим требованиям.
Davidvew
10 Sep 25 at 9:11 am
If you wish for to improve your experience just keep visiting this
website and be updated Niagara Falls Day Trip with Boat Cruise the most
recent information posted here.
Niagara Falls Day Trip with Boat Cruise
10 Sep 25 at 9:14 am
Luxury1288
Luxury1288
10 Sep 25 at 9:15 am
купить диплом о среднем образовании [url=www.educ-ua9.ru]купить диплом о среднем образовании[/url] .
Diplomi_sipr
10 Sep 25 at 9:16 am
Купить диплом колледжа в Донецк [url=http://educ-ua8.ru]Купить диплом колледжа в Донецк[/url] .
Diplomi_vzpt
10 Sep 25 at 9:16 am
Эта статья для ознакомления предлагает читателям общее представление об актуальной теме. Мы стремимся представить ключевые факты и идеи, которые помогут читателям получить представление о предмете и решить, стоит ли углубляться в изучение.
Почему это важно? – https://blog.rsgtecnologia.com/por-que-sua-empresa-precisa-de-um-website-para-sobreviver-no-mercado
AlbertDox
10 Sep 25 at 9:16 am
авиатор 1хбет [url=https://aviator-igra-3.ru/]авиатор 1хбет[/url] .
aviator igra_wumi
10 Sep 25 at 9:17 am
похожа на соль в криисталлахс на вкус че?
https://www.impactio.com/researcher/ikyyograj
Рто ошибка или нет, подскажи пожалуйста.
BrianNeins
10 Sep 25 at 9:18 am
Этот обзорный материал предоставляет информационно насыщенные данные, касающиеся актуальных тем. Мы стремимся сделать информацию доступной и структурированной, чтобы читатели могли легко ориентироваться в наших выводах. Познайте новое с нашим обзором!
Не упусти важное! – https://enpublico.mx/2023/01/06/hallan-en-la-sierra-cuerpo-de-doctora-desaparecida
Caseyfuh
10 Sep 25 at 9:18 am
Эта публикация завернет вас в вихрь увлекательного контента, сбрасывая стереотипы и открывая двери к новым идеям. Каждый абзац станет для вас открытием, полным ярких примеров и впечатляющих достижений. Подготовьтесь быть вовлеченными и удивленными каждый раз, когда продолжите читать.
Исследовать вопрос подробнее – https://themonamarshall.com/indian-bride-traditions
JohnnyFrits
10 Sep 25 at 9:18 am
If some one desires expert view regarding blogging after that i advise him/her to pay a quick visit this weblog, Keep up the good job.
dat hang trung quoc
10 Sep 25 at 9:20 am
https://omsi2mod.ru/forum/12-7061-1
https://omsi2mod.ru/forum/12-7061-1
10 Sep 25 at 9:20 am
flight game money [url=http://www.aviator-igra-3.ru]http://www.aviator-igra-3.ru[/url] .
aviator igra_mtmi
10 Sep 25 at 9:21 am
В данной статье вы найдете комплексный подход к изучению насущных тем. Мы комбинируем теоретические сведения с практическими советами, чтобы читатель мог не только понять проблему, но и найти пути её решения.
Раскрыть тему полностью – https://taranehkhavidi.com/hello-world
JohnnyFrits
10 Sep 25 at 9:23 am
Estou completamente alucinado por MonsterWin Casino, e um cassino online que ruge como uma fera braba. Tem uma avalanche de jogos de cassino irados, com slots de cassino unicos e explosivos. O atendimento ao cliente do cassino e um monstro de eficiencia, acessivel por chat ou e-mail. Os ganhos do cassino chegam voando como um dragao, de vez em quando mais giros gratis no cassino seria uma loucura. No fim das contas, MonsterWin Casino e o point perfeito pros fas de cassino para os cacadores de slots modernos de cassino! De lambuja a plataforma do cassino detona com um visual que e puro rugido, aumenta a imersao no cassino a mil.
monsterwin games|
goofykraken5zef
10 Sep 25 at 9:24 am
купить диплом о высшем образовании [url=www.educ-ua2.ru]купить диплом о высшем образовании[/url] .
Diplomi_vwOt
10 Sep 25 at 9:25 am
of course like your website however you need to take a look at the spelling on several of your posts.
A number of them are rife with spelling problems and I to find it very bothersome to inform
the truth on the other hand I’ll certainly
come again again.
Pink Salt Recipe Reviews
10 Sep 25 at 9:25 am
купить аттестат за 11 классов с занесением в реестр в [url=http://arus-diplom25.ru/]купить аттестат за 11 классов с занесением в реестр в[/url] .
Diplomi_vvot
10 Sep 25 at 9:27 am
Этот информативный текст выделяется своими захватывающими аспектами, которые делают сложные темы доступными и понятными. Мы стремимся предложить читателям глубину знаний вместе с разнообразием интересных фактов. Откройте новые горизонты и развивайте свои способности познавать мир!
Не упусти важное! – https://www.exportamos.info/contratos-comerciales-internacionales-por-que-son-tan-importantes-para-los-exportadores
Curtiscoure
10 Sep 25 at 9:29 am
Everything is very open with a precise description of the issues.
It was really informative. Your site is very useful.
Many thanks for sharing!
Daily Tarot Reading Now
10 Sep 25 at 9:29 am
В этой публикации мы предлагаем подробные объяснения по актуальным вопросам, чтобы помочь читателям глубже понять их. Четкость и структурированность материала сделают его удобным для усвоения и применения в повседневной жизни.
Переходите по ссылке ниже – https://pei-studyabroad.com/sample-post1
Frankval
10 Sep 25 at 9:30 am
darknet markets dark web link darknet site [url=https://darkmarketslegion.com/ ]nexus darknet url [/url]
DwayneAricE
10 Sep 25 at 9:30 am
авиатор онлайн игра [url=www.aviator-igra-2.ru]авиатор онлайн игра[/url] .
aviator igra_ojol
10 Sep 25 at 9:31 am
fdhfkfk
fdhfkfkbr
10 Sep 25 at 9:31 am