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!
sweet bonanza gameplay https://www.sweet-bonanza3003.ru
В условиях, когда алкогольная зависимость угрожает жизни, оперативное вмешательство становится ключевым фактором для сохранения здоровья. В Рязани круглосуточная помощь нарколога на дому позволяет начать комплексное лечение запоя и алкогольной интоксикации в самые критические моменты. Такая услуга обеспечивает детоксикацию организма, стабилизацию жизненно важных показателей и психологическую поддержку, что способствует скорейшему восстановлению в комфортной обстановке, без необходимости посещения стационара.
Выяснить больше – http://narcolog-na-dom-ryazan0.ru
Эта публикация содержит ценные советы и рекомендации по избавлению от зависимости. Мы обсуждаем различные стратегии, которые могут помочь в процессе выздоровления и важность обращения за помощью. Читатели смогут использовать полученные знания для улучшения своего состояния.
Узнать больше – нарколог на дом срочно
Этот медицинский обзор сосредоточен на последних достижениях, которые оказывают влияние на пациентов и медицинскую практику. Мы разбираем инновационные методы лечения и исследований, акцентируя внимание на их значимости для общественного здоровья. Читатели узнают о свежих данных и их возможном применении.
Разобраться лучше – вызов нарколога на дом
sweet bonanza 7 slot http://sweet-bonanza3004.ru
В этой публикации мы исследуем ключевые аспекты здоровья, включая влияние образа жизни на благополучие. Читатели узнают о важности правильного питания, физической активности и психического здоровья. Мы предоставим практические советы и рекомендации для поддержания здоровья и развития профилактических подходов.
Получить больше информации – выезд нарколога на дом
mostbet link http://www.mostbet4004.ru
Этот медицинский обзор сосредоточен на последних достижениях, которые оказывают влияние на пациентов и медицинскую практику. Мы разбираем инновационные методы лечения и исследований, акцентируя внимание на их значимости для общественного здоровья. Читатели узнают о свежих данных и их возможном применении.
Исследовать вопрос подробнее – выезд нарколога на дом
Специалист уточняет, сколько времени продолжается запой, какой тип алкоголя употребляется, а также наличие сопутствующих заболеваний. Тщательный анализ этих данных помогает определить оптимальные методы детоксикации и скорректировать терапевтическую стратегию для минимизации риска осложнений.
Узнать больше – https://narcolog-na-dom-ryazan0.ru/
1win crash game [url=https://1win3007.com]https://1win3007.com[/url]
sweet bonanza sweet bonanza
partner 1win partner 1win
Алкогольная интоксикация и запой могут стремительно ухудшить состояние здоровья, став угрозой жизни, поэтому оперативное вмешательство имеет первостепенное значение. В Туле квалифицированные наркологи предоставляют круглосуточную помощь на дому, что позволяет начать лечение незамедлительно и в комфортных условиях. Такой формат терапии гарантирует индивидуальный подход, всестороннюю поддержку и полную конфиденциальность, что особенно важно для пациентов, стремящихся восстановить своё здоровье без лишних стрессовых ситуаций.
Получить дополнительные сведения – вывод из запоя на дому
Системы автоматизированного дозирования обеспечивают точное введение медикаментов, что минимизирует риск побочных эффектов. Постоянный мониторинг жизненно важных показателей позволяет врачу корректировать терапию в режиме реального времени, гарантируя безопасность процедуры.
Разобраться лучше – https://vyvod-iz-zapoya-vladimir0.ru
I have read so many articles or reviews concerning the blogger lovers except
this post is actually a fastidious article, keep it up.
I wanted to thank you for this very good read!!
I certainly enjoyed every bit of it. I have you book-marked to look at new things you post…
Семейный портал https://stepandstep.com.ua статьи для родителей, игры и развивающие материалы для детей, советы психологов, лайфхаки.
Клуб родителей https://entertainment.com.ua пространство поддержки, общения и обмена опытом.
Всё о спорте https://beachsoccer.com.ua в одном месте: профессиональный и любительский спорт, фитнес, здоровье, техника упражнений и спортивное питание.
Туристический портал https://aliana.com.ua с лучшими маршрутами, подборками стран, бюджетными решениями, гидами и советами.
Системы автоматизированного дозирования обеспечивают точное введение медикаментов, что минимизирует риск побочных эффектов. Постоянный мониторинг жизненно важных показателей позволяет врачу корректировать терапию в режиме реального времени, гарантируя безопасность процедуры.
Узнать больше – http://vyvod-iz-zapoya-vladimir0.ru/
В этой статье рассматриваются различные аспекты избавления от зависимости, включая физические и психологические методы. Мы обсудим поддержку, мотивацию и стратегии, которые помогут в процессе выздоровления. Читатели узнают, как преодолеть трудности и двигаться к новой жизни без зависимости.
Подробнее можно узнать тут – вызов нарколога на дом
mostbet a android https://www.mostbet4004.ru
зайти в мостбет http://mostbet4013.ru
Системы автоматизированного дозирования обеспечивают точное введение медикаментов, что минимизирует риск побочных эффектов. Постоянный мониторинг жизненно важных показателей позволяет врачу корректировать терапию в режиме реального времени, гарантируя безопасность процедуры.
Детальнее – https://vyvod-iz-zapoya-vladimir0.ru/srochnyj-vyvod-iz-zapoya-vladimir
В этой статье мы рассматриваем разрушительное влияние зависимости на жизнь человека. Обсуждаются аспекты, такие как здоровье, отношения и профессиональные достижения. Читатели узнают о необходимости обращения за помощью и о путях к восстановлению.
Получить дополнительные сведения – https://narkolog-na-dom-krasnodar12.ru/
Эта публикация исследует взаимосвязь зависимости и психологии. Мы обсудим, как психологические аспекты влияют на появление зависимостей и процесс выздоровления. Читатели смогут понять важность профессиональной поддержки и применения научных подходов в терапии.
Получить дополнительную информацию – narkolog-na-dom-czena
Pretty nice post. I just stumbled upon your weblog and wished to say that I have truly
enjoyed surfing around your blog posts. In any case I’ll be subscribing to your rss
feed and I hope you write again very soon!
Эта публикация обращает внимание на важность профилактики зависимостей. Мы обсудим, как осведомленность и образование могут помочь в предотвращении возникновения зависимости. Читатели смогут ознакомиться с полезными советами и ресурсами, которые способствуют здоровому образу жизни.
Получить больше информации – нарколог на дом цена
Запой характеризуется накоплением токсинов и ухудшением работы внутренних органов. Чем дольше продолжается состояние интоксикации, тем выше риск серьезных осложнений. Помощь нарколога на дому позволяет начать детоксикацию в первые часы кризиса, что существенно повышает шансы на успешное восстановление и предотвращает развитие хронических заболеваний.
Ознакомиться с деталями – вывод из запоя стационар владимир
Системы автоматизированного дозирования обеспечивают точное введение медикаментов, что минимизирует риск побочных эффектов. Постоянный мониторинг жизненно важных показателей позволяет врачу корректировать терапию в режиме реального времени, гарантируя безопасность процедуры.
Подробнее – вывод из запоя
В этом обзоре представлены различные методы избавления от зависимости, включая терапевтические и психологические подходы. Мы сравниваем их эффективность и предоставляем рекомендации для тех, кто хочет вернуться к трезвой жизни. Читатели смогут найти информацию о реабилитационных центрах и поддерживающих группах.
Разобраться лучше – нарколог на дом
Семейный портал https://stepandstep.com.ua статьи для родителей, игры и развивающие материалы для детей, советы психологов, лайфхаки.
Туристический портал https://aliana.com.ua с лучшими маршрутами, подборками стран, бюджетными решениями, гидами и советами.
автоломбард москва под залог птс в москве
24avtolombard-pts65.ru
займ под птс без посещения офиса
Клуб родителей https://entertainment.com.ua пространство поддержки, общения и обмена опытом.
Всё о спорте https://beachsoccer.com.ua в одном месте: профессиональный и любительский спорт, фитнес, здоровье, техника упражнений и спортивное питание.
В этом исследовании рассмотрены методы лечения зависимостей и их эффективность. Мы проанализируем различные подходы, используемые в реабилитационных центрах, и представим данные о результативности программ. Читатели получат надежные и научно обоснованные сведения о данной проблеме.
Получить больше информации – нарколог на дом
Hey! Quick question that’s completely off topic.
Do you know how to make your site mobile friendly? My website looks weird when browsing from my iphone4.
I’m trying to find a template or plugin that might
be able to fix this issue. If you have any recommendations,
please share. Many thanks!
Shop premium research chemicals online from a trusted USA source.
Safe payment, fast delivery & lab-tested quality.
Buy now discreetly and legally. Looking to buy research chemicals online?
Get high-purity, lab-tested compounds shipped discreetly to your door.
USA customers welcome!
В этом обзоре мы обсудим современные методы борьбы с зависимостями, включая медикаментозную терапию и психотерапию. Мы представим последние исследования и их результаты, чтобы читатели могли быть в курсе наиболее эффективных подходов к лечению и поддержке.
Подробнее можно узнать тут – нарколог на дом
Great article.
Способности — это функции, действующие на основании поведения и окружения. НЛП связывает функционирование нервной системы с языком. Универсальная метамодель пирамида Короткова.
Эти данные являются основой для составления индивидуального плана лечения, позволяющего оперативно скорректировать терапевтические меры.
Подробнее тут – http://narcolog-na-dom-ryazan00.ru/vyzov-narkologa-na-dom-ryazan/
Этот документ охватывает важные аспекты медицинской науки, сосредотачиваясь на ключевых вопросах, касающихся здоровья населения. Мы рассматриваем свежие исследования, клинические рекомендации и лучшие практики, которые помогут улучшить качество лечения и профилактики заболеваний. Читатели получат возможность углубиться в различные медицинские дисциплины.
Изучить вопрос глубже – вызов врача нарколога на дом
videos 1win https://1win3003.com
Одним из основных этапов вывода из запоя является медикаментозная детоксикация. Современные препараты вводятся капельничным методом, что обеспечивает быстрое снижение уровня алкоголя и токсинов в крови. Это позволяет восстановить нормальный обмен веществ и нормализовать работу жизненно важных органов, таких как печень, почки и сердце. Такой подход помогает не только стабилизировать состояние пациента, но и уменьшить риск развития осложнений.
Углубиться в тему – вывод из запоя
Услуга вывода из запоя на дому в Туле разработана для тех, кто столкнулся с тяжелыми последствиями злоупотребления алкоголем. Основная цель – оперативная детоксикация организма, восстановление нормального обмена веществ и предотвращение дальнейших осложнений. Врач нарколог проводит полный комплекс обследований и назначает персонализированный план лечения, включающий медикаментозную терапию и психологическую поддержку, что позволяет обеспечить стабильное восстановление организма.
Узнать больше – https://vyvod-iz-zapoya-tula000.ru/
Howdy! Someone in my Myspace group shared this website with us so I came to take
a look. I’m definitely enjoying the information. I’m bookmarking and will be tweeting
this to my followers! Fantastic blog and terrific style and
design.
Thanks for some other informative web site. The place
else may just I get that type of info written in such an ideal way?
I have a venture that I’m just now operating
on, and I have been on the look out for such information.