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://frei-diplom1.ru]как купить диплом с реестром[/url] .
Diplomi_bbOi
1 Nov 25 at 5:37 am
What’s up to every single one, it’s truly a nice for me to
pay a quick visit this web site, it contains important Information.
تعمیرات مایکروفر پاناسونیک در تهران
1 Nov 25 at 5:38 am
медсестра которая купила диплом врача [url=http://www.frei-diplom13.ru]медсестра которая купила диплом врача[/url] .
Diplomi_lskt
1 Nov 25 at 5:39 am
купить диплом в ноябрьске [url=www.rudik-diplom2.ru]купить диплом в ноябрьске[/url] .
Diplomi_qjpi
1 Nov 25 at 5:39 am
купить диплом в шахтах [url=www.rudik-diplom4.ru]www.rudik-diplom4.ru[/url] .
Diplomi_tiOr
1 Nov 25 at 5:39 am
купить диплом в рыбинске [url=rudik-diplom8.ru]rudik-diplom8.ru[/url] .
Diplomi_ypMt
1 Nov 25 at 5:40 am
купить диплом в нижневартовске [url=www.rudik-diplom9.ru]www.rudik-diplom9.ru[/url] .
Diplomi_cjei
1 Nov 25 at 5:40 am
купить диплом агронома [url=www.rudik-diplom3.ru]купить диплом агронома[/url] .
Diplomi_azei
1 Nov 25 at 5:41 am
купить диплом в великих луках [url=www.rudik-diplom10.ru/]купить диплом в великих луках[/url] .
Diplomi_vpSa
1 Nov 25 at 5:41 am
купить свидетельство о браке [url=http://www.rudik-diplom11.ru]купить свидетельство о браке[/url] .
Diplomi_egMi
1 Nov 25 at 5:42 am
диплом о высшем образовании с занесением в реестр купить [url=www.frei-diplom4.ru]диплом о высшем образовании с занесением в реестр купить[/url] .
Diplomi_xbOl
1 Nov 25 at 5:42 am
купить диплом о среднем техническом образовании [url=educ-ua7.ru]educ-ua7.ru[/url] .
Diplomi_nfea
1 Nov 25 at 5:42 am
купить медицинский диплом с занесением в реестр [url=frei-diplom1.ru]купить медицинский диплом с занесением в реестр[/url] .
Diplomi_hkOi
1 Nov 25 at 5:43 am
купить диплом в абакане [url=rudik-diplom4.ru]купить диплом в абакане[/url] .
Diplomi_srOr
1 Nov 25 at 5:43 am
купить диплом без занесения в реестр [url=http://www.frei-diplom6.ru]купить диплом без занесения в реестр[/url] .
Diplomi_vfOl
1 Nov 25 at 5:43 am
affordable medication Ireland: irishpharmafinder – Irish Pharma Finder
HaroldSHems
1 Nov 25 at 5:43 am
кто нибудь работает медсестрой по купленному диплому [url=http://frei-diplom13.ru/]http://frei-diplom13.ru/[/url] .
Diplomi_cakt
1 Nov 25 at 5:45 am
купить диплом с реестром в москве [url=http://www.frei-diplom4.ru]купить диплом с реестром в москве[/url] .
Diplomi_yuOl
1 Nov 25 at 5:45 am
куплю диплом с занесением [url=www.rudik-diplom11.ru/]куплю диплом с занесением[/url] .
Diplomi_yfMi
1 Nov 25 at 5:46 am
купить диплом института с реестром [url=https://www.frei-diplom1.ru]купить диплом института с реестром[/url] .
Diplomi_wbOi
1 Nov 25 at 5:47 am
купить диплом с занесением в реестр в москве [url=frei-diplom5.ru]купить диплом с занесением в реестр в москве[/url] .
Diplomi_zjPa
1 Nov 25 at 5:47 am
можно ли купить диплом [url=https://rudik-diplom8.ru/]можно ли купить диплом[/url] .
Diplomi_lvMt
1 Nov 25 at 5:47 am
купить дипломы о высшем с занесением [url=http://www.rudik-diplom3.ru]купить дипломы о высшем с занесением[/url] .
Diplomi_snei
1 Nov 25 at 5:47 am
Купить диплом колледжа в Ивано-Франковск [url=www.educ-ua7.ru/]www.educ-ua7.ru/[/url] .
Diplomi_juea
1 Nov 25 at 5:48 am
где можно купить диплом медсестры [url=https://frei-diplom13.ru/]где можно купить диплом медсестры[/url] .
Diplomi_qakt
1 Nov 25 at 5:48 am
купить диплом с занесением в реестр [url=http://rudik-diplom5.ru]купить диплом с занесением в реестр[/url] .
Diplomi_nbma
1 Nov 25 at 5:49 am
купить диплом вуза занесением реестр [url=frei-diplom6.ru]frei-diplom6.ru[/url] .
Diplomi_toOl
1 Nov 25 at 5:49 am
купить диплом в кемерово [url=https://rudik-diplom10.ru/]купить диплом в кемерово[/url] .
Diplomi_xrSa
1 Nov 25 at 5:50 am
купить диплом лаборанта [url=https://www.rudik-diplom3.ru]купить диплом лаборанта[/url] .
Diplomi_gnei
1 Nov 25 at 5:51 am
купить диплом с занесением в реестр в спб [url=www.frei-diplom5.ru]www.frei-diplom5.ru[/url] .
Diplomi_gkPa
1 Nov 25 at 5:52 am
купить диплом массажиста [url=rudik-diplom5.ru]купить диплом массажиста[/url] .
Diplomi_rrma
1 Nov 25 at 5:53 am
J’ai une affection particuliere pour Sugar Casino, ca offre une experience immersive. La variete des jeux est epoustouflante, comprenant des jeux crypto-friendly. Il rend le debut de l’aventure palpitant. Les agents repondent avec rapidite. Les paiements sont surs et efficaces, a l’occasion quelques spins gratuits en plus seraient top. Pour conclure, Sugar Casino offre une aventure memorable. De plus l’interface est lisse et agreable, ce qui rend chaque session plus excitante. A mettre en avant les paiements securises en crypto, qui stimule l’engagement.
Commencer Г lire|
skymindus5zef
1 Nov 25 at 5:53 am
В этом информативном тексте представлены захватывающие события и факты, которые заставят вас задуматься. Мы обращаем внимание на важные моменты, которые часто остаются незамеченными, и предлагаем новые перспективы на привычные вещи. Подготовьтесь к тому, чтобы быть поглощенным увлекательными рассказами!
Перейти к полной версии – https://currentdrive.pl/logo-2
WilliamTop
1 Nov 25 at 5:55 am
Купить диплом техникума в Киев [url=educ-ua7.ru]educ-ua7.ru[/url] .
Diplomi_jrea
1 Nov 25 at 5:55 am
купить диплом в тобольске [url=rudik-diplom12.ru]rudik-diplom12.ru[/url] .
Diplomi_uuPi
1 Nov 25 at 5:56 am
купить диплом архитектора [url=www.rudik-diplom10.ru]купить диплом архитектора[/url] .
Diplomi_uuSa
1 Nov 25 at 5:56 am
купить диплом техникума с реестром [url=www.frei-diplom6.ru]купить диплом техникума с реестром[/url] .
Diplomi_khOl
1 Nov 25 at 5:56 am
карниз для штор электрический [url=http://www.elektrokarniz499.ru]карниз для штор электрический[/url] .
elektrokarniz_rsKl
1 Nov 25 at 5:57 am
купить диплом в новосибирске [url=http://rudik-diplom4.ru/]купить диплом в новосибирске[/url] .
Diplomi_guOr
1 Nov 25 at 5:57 am
В Ростове-на-Дону клиника «ЧСП№1» предлагает квалифицированный вывод из запоя в стационаре и на дому.
Разобраться лучше – [url=https://vyvod-iz-zapoya-rostov28.ru/]вывод из запоя на дому цена в ростове-на-дону[/url]
RichardLop
1 Nov 25 at 5:57 am
купить диплом с проводкой одной [url=http://frei-diplom4.ru/]купить диплом с проводкой одной[/url] .
Diplomi_eoOl
1 Nov 25 at 5:58 am
купить диплом с занесением в реестр москва [url=http://frei-diplom5.ru/]купить диплом с занесением в реестр москва[/url] .
Diplomi_kePa
1 Nov 25 at 5:59 am
электрические гардины [url=elektrokarniz499.ru]электрические гардины[/url] .
elektrokarniz_goKl
1 Nov 25 at 6:00 am
Mums and Dads, competitive approach engaged lah, strong primary maths гesults tⲟ superior scientific understanding ρlus construction goals.
Ⲟһ, math acts lіke thе foundation stone fⲟr primary schooling, helping children ѡith spatial thinking tօ architecture
careers.
River Valey Нigh School Junior College integrates bilingualism ɑnd ecological stewardship,
developing eco-conscious leaders ᴡith global viewpoints.
Advanced laboratories аnd green efforts support advanced knowing іn sciences аnd humanities.
Students participate іn cultural immersions and service jobs, boosting empathy аnd skills.
Τhe school’ѕ unified neighborhood promotes strength аnd
tea effort tһrough sports and arts. Graduates ɑге prepared fߋr success in universities and beyοnd, embodying perseverance ɑnd cultural acumen.
Jurong Pioneer Junior College, developed thгough tһe thoughtful merger оf Jurong Junior College and Pioneer Junior College, рrovides a progressive ɑnd future-oriented education tһat puts a special focus
оn China readiness, international organization acumen,
аnd cross-cultural engagement tο prepare students fߋr thriving in Asia’s dynamic financial landscape.
Τhe college’ѕ dual campuses aгe equipped
witһ contemporary, versatile centers consisting ߋf specialized commerce simulation гooms,
science innovation laboratories, аnd arts ateliers, all created to foster usefᥙl skills, creativity, аnd interdiscipolinary
knowing. Enriching academic programs are matched Ьy worldwide collaborations, ѕuch aѕ joint projects ᴡith
Chinese universities ɑnd cultural immersion journeys, whіch enhance trainees’ linguistic efficiency ɑnd international outlook.
А supportive аnd inclusive community atmosphere motivates strength and management development tһrough
a vast array οf co-curricular activities, fгom entrepreneurship
сlubs to sports groups tһɑt promote teamwork ɑnd
determination. Graduates ⲟf Jurong Pioneer Junior College ɑгe
incredibly ԝell-prepared fοr competitive professions, embodying
tһe values of care, constant improvement, ɑnd innovation tһat spеcify tthe institution’ѕ positive
ethos.
Parents, kiasu mode engaged lah, robust primary maths
гesults іn better science understanding ɑs wеll аs tech dreams.
Wow, math is the base stone fоr primary schooling,
assisting youngsters ԝith geometric reasoning tߋ building paths.
Ꭺvoid mess around lah, combine а ɡood Junior College
ԝith mathematics superiority in order to ensure high A Levels scores
ɑnd smooth shifts.
Alas, primary maths educates everyday applications including money management,
tһerefore make sᥙrе your kid gets it correctly starting уoung.
Hey hey, steady pom pi pі, maths proves рart of the toр disciplines аt
Junior College, building groundwork іn A-Level calculus.
In adԁition to school facilities, concentrate ᴡith
math for аvoid typical mistakes including inattentive mistakes іn assessments.
Strong Math scores ᧐pen սр actuarial science, а
hіgh-paying field in Singapore.
Wah, math acts ⅼike tһe groundwork stone of primary
learning, assisting children fⲟr geometric analysis fօr architecture
routes.
Aiyo, mіnus robust math іn Junior College, even leading institution kids coulⅾ struggle іn hiɡh school equations, ѕo develop іt immeⅾiately leh.
mʏ homepage; junior colleges singapore
junior colleges singapore
1 Nov 25 at 6:00 am
купить диплом тренера [url=https://www.rudik-diplom7.ru]купить диплом тренера[/url] .
Diplomi_hyPl
1 Nov 25 at 6:00 am
купить аттестат за 9 класс [url=https://www.rudik-diplom11.ru]купить аттестат за 9 класс[/url] .
Diplomi_hnMi
1 Nov 25 at 6:01 am
https://t.me/s/ud_1xbet/62
MichaelPione
1 Nov 25 at 6:04 am
купить диплом в череповце [url=www.rudik-diplom10.ru]www.rudik-diplom10.ru[/url] .
Diplomi_vwSa
1 Nov 25 at 6:04 am
Hi colleagues, its impressive piece of writing concerning cultureand fully defined,
keep it up all the time.
Klik disini
1 Nov 25 at 6:05 am
купить диплом с проводкой одно [url=www.frei-diplom1.ru]купить диплом с проводкой одно[/url] .
Diplomi_kyOi
1 Nov 25 at 6:05 am