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!
It is perfect time to make a few plans for the future and it is
time to be happy. I have read this publish and
if I could I want to recommend you few attention-grabbing things or suggestions.Maybe you can write subsequent articles relating
to this article. I wish to read more things about it!
Hi, Neat post. There is an issue along with your web site
in web explorer, may test this? IE nonetheless is the marketplace
leader and a good section of folks will leave out your excellent writing because of this problem.
mostbet kg скачать на андроид mostbet11008.ru
Thanks , I’ve recently been searching for info about this topic for ages and yours is the greatest I have came upon till now.
But, what about the bottom line? Are you certain in regards to
the source?
купить школьный аттестат купить школьный аттестат .
Wassup guys, I’m Ivan from Croatia. I wanna tell you about
my insane experience with this new online casino I stumbled on not long
ago.
To be honest, I was barely affording rent, and
now I can’t believe it myself — I crushed it and made $1,
500,000 playing mostly slots!
Now I’m thinking of getting a new car here in Split, and investing a serious
chunk of my winnings into Toncoin.
Later I’ll probably move to a better neighborhood and travel the world.
Now I’m going by Nikola from Serbia because I honestly feel like a
new person. My life is flipping upside down in the best way.
Let’s be honest, what would you guys do if you had this kinda luck?
Are you wondering if it’s real right now?
For real, I never thought I’d have a shot at investing.
It’s all happening so fast!
Drop your thoughts below!
регистрация в бк мостбет регистрация в бк мостбет
Бездепозитный бонус в казино Бездепозитные бонусы
mostbet.com mostbet.com
купить диплом в благовещенске купить диплом в благовещенске .
займ под залог авто екатеринбург
zaimpod-pts89.ru/ekb.html
деньги под птс автомобиля екатеринбург
диплом купить в новосибирске [url=arus-diplom6.ru]диплом купить в новосибирске[/url] .
купить диплом об окончании техникума [url=https://www.arus-diplom4.ru]https://www.arus-diplom4.ru[/url] .
Fantastic website. A lot of helpful information here.
I’m sending it to some friends ans additionally sharing in delicious.
And certainly, thanks to your sweat!
купить аттестат старого образца [url=https://www.arus-diplom5.ru]https://www.arus-diplom5.ru[/url] .
Покупка дипломов ВУЗов по всей России и СНГ — с печатями, подписями, приложением и возможностью архивной записи (по запросу).
Документ максимально приближен к оригиналу и проходит визуальную проверку.
Мы даем гарантию, что в случае проверки документа, подозрений не возникнет.
– Конфиденциально
– Доставка 3–7 дней
– Любая специальность
Уже более 3602 клиентов воспользовались услугой — теперь ваша очередь.
Пишите в личные сообщения — ответим быстро, без лишних формальностей.
скачать приложения 888 starz скачать приложения 888 starz .
скачать 888starz на телефон скачать 888starz на телефон .
Оформиление дипломов ВУЗов в Москве — с печатями, подписями, приложением и возможностью архивной записи (по запросу).
Документ максимально приближен к оригиналу и проходит визуальную проверку.
Мы гарантируем, что в случае проверки документа, подозрений не возникнет.
– Конфиденциально
– Доставка 3–7 дней
– Любая специальность
Уже более 4227 клиентов воспользовались услугой — теперь ваша очередь.
Купить диплом о среднем образовании — ответим быстро, без лишних формальностей.
888starz сайт 888starz сайт .
888 starz официальный сайт скачать http://888starz-starz888.ru/ .
Оформиление дипломов ВУЗов по всей России и СНГ — с печатями, подписями, приложением и возможностью архивной записи (по запросу).
Документ максимально приближен к оригиналу и проходит визуальную проверку.
Мы даем гарантию, что в случае проверки документа, подозрений не возникнет.
– Конфиденциально
– Доставка 3–7 дней
– Любая специальность
Уже более 1657 клиентов воспользовались услугой — теперь ваша очередь.
[url=http://inforepetitor7.ru/]Диплом цена[/url] — ответим быстро, без лишних формальностей.
Hi to all, how is the whole thing, I think every one is getting more from this site, and your views are fastidious
designed for new viewers.
скачать приложение 888starz [url=www.888starz-starz888.ru]скачать приложение 888starz[/url] .
888starz официальный [url=http://www.888starz-starz888.ru]888starz официальный[/url] .
mostbet uz slotlar mostbet uz slotlar
Покупка дипломов ВУЗов в Москве — с печатями, подписями, приложением и возможностью архивной записи (по запросу).
Документ максимально приближен к оригиналу и проходит визуальную проверку.
Мы даем гарантию, что в случае проверки документа, подозрений не возникнет.
– Конфиденциально
– Доставка 3–7 дней
– Любая специальность
Уже более 3414 клиентов воспользовались услугой — теперь ваша очередь.
Ознакомиться здесь — ответим быстро, без лишних формальностей.
Very energetic article, I liked that bit. Will there be a part 2?
Take a look at my homepage: game
Попался офигенный сайт с бесплатным порно xhub-ru.cc! Вот тут мое любимое порно: https://xhub-ru.cc/studenty/3832-studentka-v-chulkah-delaet-minet-i-trahaetsja-rakom.html — море годного порно бесплатно! Рекомендую всем!
Оформиление дипломов ВУЗов в Москве — с печатями, подписями, приложением и возможностью архивной записи (по запросу).
Документ максимально приближен к оригиналу и проходит визуальную проверку.
Мы гарантируем, что в случае проверки документа, подозрений не возникнет.
– Конфиденциально
– Доставка 3–7 дней
– Любая специальность
Уже более 1652 клиентов воспользовались услугой — теперь ваша очередь.
Доступ по ссылке — ответим быстро, без лишних формальностей.
Мы предлагаем оформление дипломов ВУЗов в Москве — с печатями, подписями, приложением и возможностью архивной записи (по запросу).
Документ максимально приближен к оригиналу и проходит визуальную проверку.
Мы даем гарантию, что в случае проверки документа, подозрений не возникнет.
– Конфиденциально
– Доставка 3–7 дней
– Любая специальность
Уже более 4953 клиентов воспользовались услугой — теперь ваша очередь.
Открыть — ответим быстро, без лишних формальностей.
букмекеры кыргызстана mostbet11004.ru
I’ve been surfing online more than 2 hours today, yet I never found any interesting
article like yours. It’s pretty worth enough for me. Personally,
if all webmasters and bloggers made good content as you did, the internet will be a lot more useful than ever before.
значки пины на заказ https://znacki-na-zakaz1.ru .
Покупка дипломов ВУЗов в Москве — с печатями, подписями, приложением и возможностью архивной записи (по запросу).
Документ максимально приближен к оригиналу и проходит визуальную проверку.
Мы гарантируем, что в случае проверки документа, подозрений не возникнет.
– Конфиденциально
– Доставка 3–7 дней
– Любая специальность
Уже более 4440 клиентов воспользовались услугой — теперь ваша очередь.
http://spbrcom8.ru/ — ответим быстро, без лишних формальностей.
значок металлический на заказ http://www.znacki-na-zakaz1.ru .
Покупка дипломов ВУЗов в Москве — с печатями, подписями, приложением и возможностью архивной записи (по запросу).
Документ максимально приближен к оригиналу и проходит визуальную проверку.
Мы гарантируем, что в случае проверки документа, подозрений не возникнет.
– Конфиденциально
– Доставка 3–7 дней
– Любая специальность
Уже более 1246 клиентов воспользовались услугой — теперь ваша очередь.
[url=http://inforepetitor9.ru/]Пишите нам[/url] — ответим быстро, без лишних формальностей.
железные значки на заказ железные значки на заказ .
It is truly a nice and helpful piece of information. I am happy that you simply
shared this useful info with us. Please keep us informed like this.
Thank you for sharing.
изготовление значков из металла на заказ москва изготовление значков из металла на заказ москва .
производство значков [url=https://znacki-na-zakaz1.ru]производство значков[/url] .
казино казино .
Мы предлагаем оформление дипломов ВУЗов по всей России и СНГ — с печатями, подписями, приложением и возможностью архивной записи (по запросу).
Документ максимально приближен к оригиналу и проходит визуальную проверку.
Мы гарантируем, что в случае проверки документа, подозрений не возникнет.
– Конфиденциально
– Доставка 3–7 дней
– Любая специальность
Уже более 1735 клиентов воспользовались услугой — теперь ваша очередь.
[url=http://spbrcom8.ru/]http://spbrcom8.ru/[/url] — ответим быстро, без лишних формальностей.
казино онлайн казино онлайн .
железные значки [url=http://znacki-na-zakaz2.ru]http://znacki-na-zakaz2.ru[/url] .
Does your site have a contact page? I’m having problems locating it but, I’d like to shoot
you an e-mail. I’ve got some recommendations for your blog you might be
interested in hearing. Either way, great website and I look forward to seeing
it improve over time.
We are a gaggle of volunteers and starting a brand new scheme in our community.
Your site provided us with valuable information to work on. You’ve done a formidable
task and our entire neighborhood can be thankful to you.
Покупка дипломов ВУЗов по всей России и СНГ — с печатями, подписями, приложением и возможностью архивной записи (по запросу).
Документ максимально приближен к оригиналу и проходит визуальную проверку.
Мы гарантируем, что в случае проверки документа, подозрений не возникнет.
– Конфиденциально
– Доставка 3–7 дней
– Любая специальность
Уже более 2093 клиентов воспользовались услугой — теперь ваша очередь.
Купить диплом института — ответим быстро, без лишних формальностей.
казино беларусь [url=http://www.kazino-online-rb.by]казино беларусь[/url] .
I loved as much as you will receive carried out right here.
The sketch is tasteful, your authored material stylish.
nonetheless, you command get bought an shakiness over that you wish be delivering the
following. unwell unquestionably come further formerly again since exactly
the same nearly very often inside case you shield this increase.