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=http://rudik-diplom15.ru]купить диплом технолога[/url] .
Diplomi_yqPi
16 Oct 25 at 9:21 am
купить диплом с проведением в [url=https://www.frei-diplom4.ru]купить диплом с проведением в[/url] .
Diplomi_laOl
16 Oct 25 at 9:23 am
mystylecorner – Felt comfortable shopping here, trustworthy feel throughout the site.
Paola Gelhar
16 Oct 25 at 9:23 am
https://t.me/Online_1_xbet/3499
CharlesCic
16 Oct 25 at 9:24 am
купить диплом воспитателя [url=www.rudik-diplom3.ru]купить диплом воспитателя[/url] .
Diplomi_zkei
16 Oct 25 at 9:24 am
https://t.me/Online_1_xbet/2710
CharlesCic
16 Oct 25 at 9:25 am
потолки натяжные в нижнем новгороде [url=https://stretch-ceilings-nizhniy-novgorod-1.ru]https://stretch-ceilings-nizhniy-novgorod-1.ru[/url] .
natyajnie potolki nijnii novgorod_xqOn
16 Oct 25 at 9:25 am
натяжной потолок дешево [url=https://stretch-ceilings-nizhniy-novgorod.ru]https://stretch-ceilings-nizhniy-novgorod.ru[/url] .
natyajnie potolki nijnii novgorod_qfPl
16 Oct 25 at 9:25 am
купить диплом электромонтера [url=http://www.rudik-diplom8.ru]купить диплом электромонтера[/url] .
Diplomi_wsMt
16 Oct 25 at 9:26 am
купить диплом образование купить проведенный диплом [url=frei-diplom6.ru]купить диплом образование купить проведенный диплом[/url] .
Diplomi_oyOl
16 Oct 25 at 9:26 am
купить диплом в волгограде [url=http://rudik-diplom11.ru]купить диплом в волгограде[/url] .
Diplomi_ziMi
16 Oct 25 at 9:28 am
потолочкин нижний новгород [url=https://stretch-ceilings-nizhniy-novgorod-1.ru]https://stretch-ceilings-nizhniy-novgorod-1.ru[/url] .
natyajnie potolki nijnii novgorod_onOn
16 Oct 25 at 9:28 am
Эта информационная статья содержит полезные факты, советы и рекомендации, которые помогут вам быть в курсе последних тенденций и изменений в выбранной области. Материал составлен так, чтобы быть полезным и понятным каждому.
Не упусти важное! – https://educationhubllp.com/why-students-from-india-should-consider-studying-mbbs-in-uzbekistan
Homerhic
16 Oct 25 at 9:29 am
купить старый диплом техникума в москве [url=https://frei-diplom10.ru]купить старый диплом техникума в москве[/url] .
Diplomi_hrEa
16 Oct 25 at 9:29 am
купить диплом в копейске [url=http://rudik-diplom5.ru/]купить диплом в копейске[/url] .
Diplomi_yvma
16 Oct 25 at 9:30 am
https://t.me/Online_1_xbet/2207
CharlesCic
16 Oct 25 at 9:30 am
https://t.me/Online_1_xbet/3303
CharlesCic
16 Oct 25 at 9:30 am
потолочников [url=http://natyazhnye-potolki-nizhniy-novgorod-1.ru/]потолочников[/url] .
natyajnie potolki nijnii novgorod_nlma
16 Oct 25 at 9:32 am
натяжной потолок в нижнем новгороде [url=www.stretch-ceilings-nizhniy-novgorod.ru/]www.stretch-ceilings-nizhniy-novgorod.ru/[/url] .
natyajnie potolki nijnii novgorod_jtPl
16 Oct 25 at 9:32 am
Онлайн-спортивный http://sportsat.ru портал: актуальные новости, обзоры игр, интервью со звёздами, результаты и аналитика. Следите за событиями в мире спорта каждый день!
sportsat-710
16 Oct 25 at 9:33 am
купить диплом в балашове [url=http://www.rudik-diplom11.ru]купить диплом в балашове[/url] .
Diplomi_qkMi
16 Oct 25 at 9:33 am
Этот информативный материал предлагает содержательную информацию по множеству задач и вопросов. Мы призываем вас исследовать различные идеи и факты, обобщая их для более глубокого понимания. Наша цель — сделать обучение доступным и увлекательным.
Запросить дополнительные данные – https://drc.uog.edu.et/life-is-good
Johnieknicy
16 Oct 25 at 9:34 am
Рейтинг лучших подоконников https://luchshie-podokonniki-iz-kamnya.ru из искусственного камня в Москве. Сравнение брендов, цены, фото и отзывы. Узнайте, какой подоконник выбрать — прочный, стильный и долговечный вариант для вашего интерьера.
podokonniki-iz-kamnya-401
16 Oct 25 at 9:35 am
потолочкин [url=http://www.natyazhnye-potolki-nizhniy-novgorod-1.ru]потолочкин[/url] .
natyajnie potolki nijnii novgorod_abma
16 Oct 25 at 9:35 am
Лазерные нивелиры – это высокоточные измерительные приборы, широко используемые в строительстве, геодезии, при отделочных работах и в ландшафтном дизайне. Они позволяют быстро и с высокой точностью определять горизонтальные и вертикальные плоскости, а также углы, что значительно упрощает и ускоряет процесс выравнивания поверхностей и установки конструкций.
Принцип работы лазерного нивелира основан на использовании лазерного луча, вращающегося или проецируемого на плоскость. Луч, проходя через оптическую систему, формирует идеально ровную линию или плоскость, которая служит эталоном для выравнивания. Это особенно удобно при заливке стяжки, установке подвесных потолков, выравнивании стен, укладке плитки или монтаже гипсокартонных конструкций. Каким должен быть качественный [url=https://airlady.forum24.ru/?1-12-0-00000055-000-0-0-1758618481]лазерный нивелир[/url]
ClaraPainy
16 Oct 25 at 9:36 am
halbzeit endstand wetten
Feel free to surf to my web page – sportwetten anmeldebonus ohne einzahlung
sportwetten anmeldebonus ohne einzahlung
16 Oct 25 at 9:36 am
натяжные потолки от производителя в нижнем новгороде [url=https://stretch-ceilings-nizhniy-novgorod-1.ru/]https://stretch-ceilings-nizhniy-novgorod-1.ru/[/url] .
natyajnie potolki nijnii novgorod_esOn
16 Oct 25 at 9:37 am
wett prognose heute
Also visit my web page – Wetten Bonus
Wetten Bonus
16 Oct 25 at 9:37 am
safe online medication store: order medicine discreetly USA – best rogue online pharmacy
Andresstold
16 Oct 25 at 9:38 am
We’re a group of volunteers and starting a new scheme in our community.
Your web site offered us with valuable info to work on. You’ve done a formidable job
and our entire community will be grateful to you.
Roofer
16 Oct 25 at 9:38 am
купить диплом в новокуйбышевске [url=https://www.rudik-diplom8.ru]купить диплом в новокуйбышевске[/url] .
Diplomi_xpMt
16 Oct 25 at 9:38 am
купить проведенный диплом отзывы [url=http://www.frei-diplom6.ru]http://www.frei-diplom6.ru[/url] .
Diplomi_nbOl
16 Oct 25 at 9:39 am
купить диплом вуза с проводкой [url=frei-diplom4.ru]frei-diplom4.ru[/url] .
Diplomi_bpOl
16 Oct 25 at 9:41 am
купить диплом о среднем специальном образовании [url=https://www.educ-ua7.ru]https://www.educ-ua7.ru[/url] .
Diplomi_mzea
16 Oct 25 at 9:42 am
натяжные потолки ру [url=https://stretch-ceilings-nizhniy-novgorod.ru]https://stretch-ceilings-nizhniy-novgorod.ru[/url] .
natyajnie potolki nijnii novgorod_uwPl
16 Oct 25 at 9:42 am
купить диплом бакалавра [url=www.rudik-diplom4.ru/]купить диплом бакалавра[/url] .
Diplomi_rfOr
16 Oct 25 at 9:42 am
натяжные потолки дешево нижний новгород [url=http://stretch-ceilings-nizhniy-novgorod-1.ru]натяжные потолки дешево нижний новгород[/url] .
natyajnie potolki nijnii novgorod_jnOn
16 Oct 25 at 9:44 am
OMT’s mindfulness techniques decrease mathematics stress ɑnd
anxiety, enabling real affection tо expand and inspire exam quality.
Join our smaⅼl-group оn-site classes in Singapore fߋr customized assistance іn a nurturing environment that constructs strong fundamental math abilities.
Аs math forms the bedrok of abstract tһought and critical problem-solving in Singapore’ѕ education system,
expert math tuition ⲟffers the tailored assistance essential tⲟ
turn difficulties intо accomplishments.
primary school math tuition constructs examination endurance tһrough timed drills,
simulating tһe PSLE’s two-paper format ɑnd assisting trainees manage time
ѕuccessfully.
Introducing heuristic methods early in secondary tuition prepares students f᧐r the non-routinetroubles tһat
օften аppear in O Level evaluations.
Fߋr those pursuing H3 Mathematics, junior college tuition supplies advanced support
օn researcһ-level topics to master thiѕ difficult extension.
OMT sticks ⲟut wіth its exclusive mathematics curriculum, carefully mаde tⲟ enhance thе Singapore MOE syllabus by filling іn theoretical voids thɑt typical school lessons
mіght ignore.
Themed components mɑke learning thematic lor, helping
keeⲣ informаtion much longer fⲟr boosted math performance.
Math tuition սsеs enreichment beyond tһe fundamentals, chuallenging gifted Singapore pupils t᧐ aim foг distinction іn exams.
Аlso visit mу site: z maths tuition
z maths tuition
16 Oct 25 at 9:45 am
Хотите узнать больше о природе нашей страны? Присоединяйтесь к обсуждению.
Хочу выделить раздел про Изучение ООПТ России: парки, заповедники, водоемы.
Ссылка ниже:
[url=https://alloopt.ru]https://alloopt.ru[/url]
Что думаете о красоте природы России? Делитесь мнениями!
fixRow
16 Oct 25 at 9:45 am
купить диплом зубного техника [url=www.rudik-diplom8.ru/]купить диплом зубного техника[/url] .
Diplomi_pxMt
16 Oct 25 at 9:47 am
That is a great tip particularly to those fresh to the blogosphere.
Short but very accurate info… Thank you for sharing this one.
A must read article!
site
16 Oct 25 at 9:47 am
потолки нижний новгород [url=http://www.natyazhnye-potolki-nizhniy-novgorod-1.ru]потолки нижний новгород[/url] .
natyajnie potolki nijnii novgorod_kvma
16 Oct 25 at 9:48 am
купить диплом реестр [url=http://frei-diplom6.ru/]купить диплом реестр[/url] .
Diplomi_wvOl
16 Oct 25 at 9:48 am
диплом о высшем образовании купить с занесением в реестр [url=http://www.frei-diplom4.ru]диплом о высшем образовании купить с занесением в реестр[/url] .
Diplomi_csOl
16 Oct 25 at 9:49 am
I am really impressed with your writing skills and also
with the layout on your weblog. Is this a paid theme or did you modify it yourself?
Either way keep up the excellent quality writing, it’s rare to see a great blog like
this one these days.
39BET
16 Oct 25 at 9:49 am
купить диплом математика [url=https://www.rudik-diplom15.ru]купить диплом математика[/url] .
Diplomi_rsPi
16 Oct 25 at 9:49 am
купить диплом без реестра [url=https://www.frei-diplom5.ru]купить диплом без реестра[/url] .
Diplomi_jbPa
16 Oct 25 at 9:49 am
компания потолочник [url=http://stretch-ceilings-nizhniy-novgorod.ru]http://stretch-ceilings-nizhniy-novgorod.ru[/url] .
natyajnie potolki nijnii novgorod_klPl
16 Oct 25 at 9:50 am
купить диплом в уфе [url=http://rudik-diplom4.ru/]купить диплом в уфе[/url] .
Diplomi_itOr
16 Oct 25 at 9:50 am
сколько стоит купить диплом техникума [url=https://educ-ua7.ru]https://educ-ua7.ru[/url] .
Diplomi_jwea
16 Oct 25 at 9:50 am