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!
Крайне рекомендую https://iphone-repair-jp.com/s001/
теннесси бк скачать на андроид бесплатно [url=https://mostbet11011.ru/]https://mostbet11011.ru/[/url]
Howdy! Do you use Twitter? I’d like to follow you if that would
be okay. I’m absolutely enjoying your blog and look forward
to new updates.
Заказать диплом о высшем образовании!
Мы изготавливаем дипломы психологов, юристов, экономистов и любых других профессий по приятным тарифам— [url=http://mplzt.ru/]mplzt.ru[/url]
деньги в долг под залог машины
zaimpod-pts89.ru/nsk.html
займ птс новосибирск
скачать мостбет кыргызстан http://www.mostbet11012.ru
Купить документ института можно у нас. Мы оказываем услуги по продаже документов об окончании любых университетов РФ. Даем гарантию, что при проверке документов работодателем, подозрений не возникнет. [url=http://postap.bestbb.ru/login.php?action=in/]postap.bestbb.ru/login.php?action=in[/url]
Бездепозитный бонус в казино Перед тем, как воспользоваться бездепозитным бонусом, стоит внимательно изучить условия его получения и отыгрыша. Важно понимать, какие игры доступны для игры на бонусные средства, какой вейджер необходимо выполнить, чтобы вывести выигрыш, и какие сроки установлены для отыгрыша бонуса. Тщательное изучение правил поможет избежать разочарований и получить максимальную выгоду от использования бонуса.
кредит под птс москва
zaimpod-pts90.ru
займ залог птс автомобиля
Купить диплом ВУЗа по невысокой цене вы можете, обратившись к проверенной специализированной фирме. Заказать диплом о высшем образовании: [url=http://jobsirish.ie/employer/premialnie-diplom-24/]jobsirish.ie/employer/premialnie-diplom-24[/url]
This article presents clear idea for the new visitors of blogging, that really how to do running a blog.
Greetings, I’m Marko from Serbia. I wanna tell you about my insane experience with this trending online casino I stumbled
on a few weeks ago.
To be honest, I was barely affording rent, and now I can’t believe it myself —
I crushed it and made $712,000 playing mostly live roulette!
Now I’m thinking of taking my dream vacation and buying a house here in Split, and investing
a serious chunk of my winnings into Cardano.
Later I’ll probably move to a better neighborhood and build my own startup.
Now I’m going by Tomasz from Poland because I honestly feel like a
new person. My life is flipping upside down in the best way.
No cap, what would you guys do if you had this kinda luck?
Are you thinking “damn!” right now?
For real, I never thought I’d be able to
help my family. It’s all happening so fast!
Reply if you wanna chat!
Мы можем предложить документы учебных заведений, которые расположены в любом регионе России. Документы выпускаются на “правильной” бумаге высшего качества: [url=http://amaderpata.com/read-blog/14191_diplom-kupit-vysshee-obrazovanie.html/]amaderpata.com/read-blog/14191_diplom-kupit-vysshee-obrazovanie.html[/url]
mostbet регистрация через официальный сайт mostbet регистрация через официальный сайт
Эта публикация содержит ценные советы и рекомендации по избавлению от зависимости. Мы обсуждаем различные стратегии, которые могут помочь в процессе выздоровления и важность обращения за помощью. Читатели смогут использовать полученные знания для улучшения своего состояния.
Ознакомиться с деталями – https://razvitie-malysha.com/vospitanie/sovety/kapelnicza-ot-alkogolya-i-ee-primenenie.html
вход в мостбет http://mostbet11009.ru/
Hello, I check your blog regularly. Your story-telling
style is awesome, keep up the good work!
This article is really a pleasant one it helps new net viewers, who
are wishing for blogging.
Hi there, You have done an excellent job. I’ll definitely digg it and personally recommend to my friends. I am sure they will be benefited from this web site.
http://comfortdeluxe.com.ua/chasti-zapytannya-pro-hermetyk-dlya-fary.html
If some one desires expert view on the topic of running a blog then i propose him/her to visit this webpage, Keep up the nice work.
мостбет ком https://mostbet11006.ru
Купить документ о получении высшего образования вы можете в нашем сервисе. Приобрести диплом ВУЗа по невысокой цене можно, обращаясь к проверенной специализированной фирме. cng.flybb.ru/viewtopic.phpf=2&t=929
Hi to every , for the reason that I am genuinely keen of reading
this weblog’s post to be updated on a regular basis.
It carries good material.
Заказать диплом университета можем помочь. Купить диплом магистра в Рязани – [url=http://diplomybox.com/kupit-diplom-magistra-v-ryazani/]diplomybox.com/kupit-diplom-magistra-v-ryazani[/url]
mostbet.com скачать mostbet.com скачать
Wassup guys, I’m Piotr from Poland. I wanna tell you about
my insane experience with this new online casino I
stumbled on this spring.
To be honest, I was living paycheck to paycheck, and now I
can’t believe it myself — I won £590,000 playing mostly live roulette!
Now I’m thinking of getting a new car here in Belgrade,
and investing a serious chunk of my winnings into Solana.
Later I’ll probably move to a better neighborhood and retire early.
Now I’m going by Andrei from Romania because I honestly feel
like a new person. My life is flipping upside down in the best way.
No cap, what would you guys do if you had this kinda luck?
Are you jealous right now?
For real, I never thought I’d get out of debt. It’s all
happening so fast!
Reply if you wanna chat!
Заказать документ ВУЗа вы сможете в нашем сервисе. Приобрести диплом ВУЗа по доступной цене можно, обратившись к проверенной специализированной компании. forestsnakes.teamforum.ru/viewtopic.phpf=28&t=6506
Мы оказываем услуги по продаже документов об окончании любых ВУЗов РФ. Документы изготавливаются на подлинных бланках. forum.sevsocium.ru/viewtopic.php?f=138&t=11577&sid=3738affecd9b39ca88614c81bf029c49
Good information. Lucky me I came across your website by accident (stumbleupon).
I’ve book marked it for later!
Заказать документ о получении высшего образования вы можете в нашей компании в Москве. Приобрести диплом института по доступной стоимости вы сможете, обратившись к надежной специализированной фирме. [url=http://mitrapura.com/kak-bystro-i-bezopasno-kupit-diplom-v-rossii-56/]mitrapura.com/kak-bystro-i-bezopasno-kupit-diplom-v-rossii-56[/url]
mostbet kg скачать http://mostbet11011.ru/
Link exchange is nothing else however it is just placing
the other person’s blog link on your page at
appropriate place and other person will also do similar in support of you.
скачат мостбет https://www.mostbet11013.ru
mostbet download [url=https://mostbet11009.ru]https://mostbet11009.ru[/url]
Мы оказываем услуги по производству и продаже документов об окончании любых университетов РФ. Документы производятся на подлинных бланках. ilk-nachalo.ru/blog.php?u=1670&b=1218
На прием Клинцы. В17 психология. 239 оценок
Бездепозитные бонусы в казино Прежде чем принять щедрое предложение от казино, стоит внимательно изучить условия предоставления бездепозитного бонуса. Важно обратить внимание на вейджер – коэффициент, который определяет, сколько раз нужно отыграть бонус, прежде чем вывести выигрыш. Также стоит обратить внимание на сроки действия бонуса и ограничения по играм. Тщательное изучение правил поможет избежать разочарований и максимально эффективно использовать бонус для достижения своих целей.
Забудь о пробках и очередях — доставка с https://clients1.google.com.bd/url?q=https://alcoclub25.ru/ решает всё за тебя. Срочно нужна бутылочка вино или ром в 3 ночи? Легко! Вся Москва обслуживается быстро и точно. Срочная доставка алкоголя — это реально. Один заказ — и праздник спасён.
диплом купить в хабаровске диплом купить в хабаровске .
мос бет mostbet11012.ru
Superb blog! Do you have any suggestions for aspiring writers?
I’m planning to start my own website soon but I’m a little lost on everything.
Would you recommend starting with a free platform like WordPress or go for
a paid option? There are so many options out there that I’m completely confused ..
Any ideas? Kudos!
I was curious if you ever considered changing the layout of your site?
Its very well written; I love what youve got to say.
But maybe you could a little more in the way of content so people
could connect with it better. Youve got an awful
lot of text for only having one or two pictures.
Maybe you could space it out better?
выигрышные live ставки на мостбет https://mostbet11013.ru/
mostbet вход в личный кабинет mostbet вход в личный кабинет
Психотерапевт Белгород. На прием Клинцы. 135 оценок
Yes! Finally something about muelear oxidize caluanie muelear
oxidize usa caluanie muelear oxidize caluanie muelear oxidize price mercury liquid price liquid mercury price
caluanie muelear oxidize price in usa red mercury price price of red mercury
mercury buy online caluanie red mercury for sale liquid
mercury buy online mercury price per pound caluanie
muelear oxidize manufacturer in usa mercury price per kg liquid mercury price
per pound liquid red mercury price red liquid mercury price red mercury
liquid price is caluanie muelear oxidize illegal caluanie muelear oxidize for
sale buy caluanie muelear oxidize caluanie muelear oxidize
manufacturer caluanie muelear.
Мы предлагаем документы об окончании любых университетов РФ. Документы производят на настоящих бланках. [url=http://blandonew.com/employer/radiplomy/]blandonew.com/employer/radiplomy[/url]
купить диплом государственного образца о высшем образовании https://www.arus-diplom2.ru .
Мы предлагаем оформление дипломов ВУЗов по всей России и СНГ — с печатями, подписями, приложением и возможностью архивной записи (по запросу).
Документ максимально приближен к оригиналу и проходит визуальную проверку.
Мы гарантируем, что в случае проверки документа, подозрений не возникнет.
– Конфиденциально
– Доставка 3–7 дней
– Любая специальность
Уже более 2029 клиентов воспользовались услугой — теперь ваша очередь.
На этой странице — ответим быстро, без лишних формальностей.
mostbet com https://mostbet11008.ru/