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=narkologicheskaya-klinika-19.ru]narkologicheskaya-klinika-19.ru[/url] .
narkologicheskaya klinika _sami
6 Oct 25 at 3:40 am
усиление грунтов [url=https://www.privetsochi.ru/blog/realty_sochi/93972.html]https://www.privetsochi.ru/blog/realty_sochi/93972.html[/url] .
ysilenie gryntov_hgSr
6 Oct 25 at 3:42 am
диплом медсестры с занесением в реестр купить [url=https://www.frei-diplom2.ru]диплом медсестры с занесением в реестр купить[/url] .
Diplomi_zgEa
6 Oct 25 at 3:43 am
поставщик медоборудования [url=https://www.medtehnika-msk.ru]https://www.medtehnika-msk.ru[/url] .
oborydovanie medicinskoe_sxpa
6 Oct 25 at 3:45 am
https://drnona-nn.ru
EdwardTrege
6 Oct 25 at 3:46 am
bestchangeru.com — Надежный Обменник Валют Онлайн
¦ Что такое BestChange?
[url=https://bestchangeru.com/]бестчендж обменник[/url]
bestchangeru.com является одним из наиболее популярных сервисов мониторинга обменников электронных валют в русскоязычном сегменте сети Интернет. Платформа была создана для упрощения процесса выбора надежного онлайн-обмена валюты среди множества предложений.
¦ Основные преимущества BestChange:
https://bestchangeru.com/
bestchange криптовалюта
– Мониторинг лучших курсов: Лучшие курсы покупки и продажи криптовалют и электронных денег автоматически обновляются в режиме реального времени.
– Автоматическое сравнение: Удобный интерфейс позволяет мгновенно сравнить десятки предложений и выбрать оптимальное.
– Обзор отзывов пользователей: Пользователи оставляют отзывы и оценки, помогающие другим пользователям принять решение.
– Отсутствие скрытых комиссий: Информация о комиссиях отображается прозрачно и открыто.
¦ Как работает BestChange?
Пользователь вводит необходимые данные: валюту, которую хочет обменять, и желаемую сумму. После этого сервис генерирует список надежных обменных пунктов с лучшими условиями обмена.
Пример: Вы хотите обменять Bitcoin на рубли. Заходите на сайт bestchangeru.com, выбираете направление обмена («Bitcoin > Рубли»), вводите сумму и получаете таблицу проверенных обменных пунктов с наилучшими курсами.
¦ Почему выбирают BestChange?
1. Безопасность. Все обменники проходят строгую проверку перед добавлением в базу сервиса.
2. Удобство пользования. Простота интерфейса позволяет быстро находить нужную информацию даже новичкам.
3. Постоянное обновление базы данных. Курсы и условия регулярно проверяются и обновляются, обеспечивая актуальность информации.
4. Многоязычность. Помимо русского, доступна версия сайта на английском и украинском языках.
Таким образом, bestchangeru.com становится незаменимым помощником в мире цифровых финансов, позволяя легко и безопасно совершать операции обмена валют. Если вам нужен надежный и удобный способ обмена криптовалюты и электронных денег, обязательно обратите внимание на этот ресурс.
AlbertSus
6 Oct 25 at 3:47 am
The other day, while I was at work, my cousin stole my iphone and tested to see
if it can survive a 30 foot drop, just so she can be a youtube sensation. My apple ipad is now destroyed and she
has 83 views. I know this is completely off topic but I had to share it with someone!
Buy Caluanie Muelear 1 Liter near me
6 Oct 25 at 3:47 am
усиление грунтов [url=https://privetsochi.ru/blog/realty_sochi/93972.html/]https://privetsochi.ru/blog/realty_sochi/93972.html/[/url] .
ysilenie gryntov_yjSr
6 Oct 25 at 3:48 am
кухни в спб на заказ [url=https://www.kuhni-spb-4.ru]https://www.kuhni-spb-4.ru[/url] .
kyhni spb_fmer
6 Oct 25 at 3:49 am
поставщик медицинского оборудования [url=www.xn—-7sbcejdfbbzea0axlidbbn0a0b5a8f.xn--p1ai/]www.xn—-7sbcejdfbbzea0axlidbbn0a0b5a8f.xn--p1ai/[/url] .
oborydovanie medicinskoe_rcsi
6 Oct 25 at 3:49 am
где купить диплом нефтяной техникум [url=https://www.frei-diplom8.ru]где купить диплом нефтяной техникум[/url] .
Diplomi_umsr
6 Oct 25 at 3:51 am
усиление грунтов [url=www.privetsochi.ru/blog/realty_sochi/93972.html/]www.privetsochi.ru/blog/realty_sochi/93972.html/[/url] .
ysilenie gryntov_bmSr
6 Oct 25 at 3:52 am
купить диплом в петропавловске-камчатском [url=http://rudik-diplom10.ru/]купить диплом в петропавловске-камчатском[/url] .
Diplomi_wtSa
6 Oct 25 at 3:53 am
купить готовый диплом техникума [url=www.frei-diplom12.ru]купить готовый диплом техникума[/url] .
Diplomi_zwPt
6 Oct 25 at 3:53 am
кухни на заказ петербург [url=https://www.kuhni-spb-4.ru]кухни на заказ петербург[/url] .
kyhni spb_rder
6 Oct 25 at 3:56 am
где купить диплом железнодорожного техникума [url=http://www.frei-diplom11.ru]где купить диплом железнодорожного техникума[/url] .
Diplomi_tfsa
6 Oct 25 at 4:00 am
зашиваться от алкоголя [url=http://www.narkologicheskaya-klinika-19.ru]http://www.narkologicheskaya-klinika-19.ru[/url] .
narkologicheskaya klinika _upmi
6 Oct 25 at 4:01 am
кухни на заказ в санкт-петербурге [url=www.kuhni-spb-2.ru]кухни на заказ в санкт-петербурге[/url] .
kyhni spb_bamn
6 Oct 25 at 4:02 am
What’s up everyone, it’s my first visit at this website, and piece of
writing is actually fruitful in favor of me, keep up posting these
types of posts.
Roblox hack 2025
6 Oct 25 at 4:02 am
Flexible pacing in OMT’ѕ е-learning aⅼlows trainees
relish math victories, developing deep love аnd ideas f᧐r exam efficiency.
Expand үour horizons wіtһ OMT’s upcoming new physical space օpening in Septеmber 2025, providing ɑ lot moгe chances for hands-᧐n math expedition.
Ꮃith students іn Singapore Ƅeginning official math education frоm ⅾay оne and dealing with higһ-stakes evaluations, math
tuition սses the additional edge needed to attain toр performance іn this importаnt subject.
Tuition programs f᧐r primary math concentrate օn error
analysis from past PSLE documents, teaching students tо prevent recurring mistakes in estimations.
Tuition helps secondary students establish test strategies,
ѕuch aѕ tіme appropriation foг the two O Level math papers,
гesulting іn far bettеr ᧐verall performance.
Ϝor those pursuing H3 Mathematics, junior college tuition рrovides sophisticated guidance on гesearch-level topics tо excel in this difficult extension.
OMT’ѕ proprietary educational program boosts MOE criteria ѵia a holistic
strategy thаt supports both scholastic skills ɑnd a passion fߋr mathematics.
OMT’ѕ οn-lіne tuition iѕ kiasu-proof leh, providing yoս
that addеɗ side to outshine in O-Level math exams.
Tuition programs іn Singapore offer simulated examinations ᥙnder timed proƅlems, replicating actual examination circumstances fοr better performance.
Ꭺlso visit mу webpage :: z math tuition eunos; koreanaggies.net,
koreanaggies.net
6 Oct 25 at 4:04 am
Когда подходит
Выяснить больше – http://narkologicheskaya-klinika-lyubercy0.ru/narkologicheskaya-klinika-na-dom-v-lyubercah/https://narkologicheskaya-klinika-lyubercy0.ru
Jorgesmusy
6 Oct 25 at 4:04 am
купить диплом техникума или колледжа [url=frei-diplom8.ru]frei-diplom8.ru[/url] .
Diplomi_kbsr
6 Oct 25 at 4:05 am
This piece of writing will help the internet users for creating new webpage or even a weblog from start to end.
Zásnubné prstene - VIPGold
6 Oct 25 at 4:06 am
купить вкладыш с оценками к диплому техникума [url=http://frei-diplom12.ru]купить вкладыш с оценками к диплому техникума[/url] .
Diplomi_jcPt
6 Oct 25 at 4:06 am
купить диплом в архангельске [url=http://rudik-diplom10.ru/]купить диплом в архангельске[/url] .
Diplomi_rdSa
6 Oct 25 at 4:07 am
наркология анонимно [url=https://narkologicheskaya-klinika-19.ru/]https://narkologicheskaya-klinika-19.ru/[/url] .
narkologicheskaya klinika _symi
6 Oct 25 at 4:09 am
усиление грунтов [url=www.privetsochi.ru/blog/realty_sochi/93972.html/]www.privetsochi.ru/blog/realty_sochi/93972.html/[/url] .
ysilenie gryntov_cgSr
6 Oct 25 at 4:10 am
кухни от производителя спб [url=http://kuhni-spb-3.ru/]кухни от производителя спб[/url] .
kyhni spb_meMr
6 Oct 25 at 4:11 am
купить кухню в спб от производителя [url=https://kuhni-spb-2.ru/]купить кухню в спб от производителя[/url] .
kyhni spb_dvmn
6 Oct 25 at 4:11 am
https://gktorg.ru
EdwardTrege
6 Oct 25 at 4:12 am
купить диплом в горном колледже [url=https://frei-diplom11.ru]https://frei-diplom11.ru[/url] .
Diplomi_unsa
6 Oct 25 at 4:14 am
купить диплом о окончании техникума официально [url=frei-diplom8.ru]купить диплом о окончании техникума официально[/url] .
Diplomi_uxsr
6 Oct 25 at 4:16 am
можно ли купить диплом [url=http://www.rudik-diplom10.ru]можно ли купить диплом[/url] .
Diplomi_xeSa
6 Oct 25 at 4:16 am
food supplement
PHP hook, building hooks in your application – Sjoerd Maessen blog at Sjoerd Maessen blog
food supplement
6 Oct 25 at 4:17 am
купить диплом техникума повара 4 разряда [url=https://www.frei-diplom12.ru]купить диплом техникума повара 4 разряда[/url] .
Diplomi_ooPt
6 Oct 25 at 4:18 am
современные кухни на заказ в спб [url=https://kuhni-spb-3.ru/]kuhni-spb-3.ru[/url] .
kyhni spb_qfMr
6 Oct 25 at 4:20 am
I loved as much as you will receive carried out right here.
The sketch is attractive, your authored material stylish.
nonetheless, you command get got an edginess over that
you wish be delivering the following. unwell unquestionably
come further formerly again since exactly the same nearly a lot often inside case you shield this hike.
situs penipu
6 Oct 25 at 4:20 am
как купить диплом техникума цена [url=http://frei-diplom9.ru]как купить диплом техникума цена[/url] .
Diplomi_uzea
6 Oct 25 at 4:20 am
кухни на заказ в санкт-петербурге [url=www.kuhni-spb-2.ru/]кухни на заказ в санкт-петербурге[/url] .
kyhni spb_cwmn
6 Oct 25 at 4:21 am
купить диплом медицинского колледжа [url=www.frei-diplom11.ru/]купить диплом медицинского колледжа[/url] .
Diplomi_yysa
6 Oct 25 at 4:23 am
RTP-nya beneran tіnggi.
link slot gacor
6 Oct 25 at 4:23 am
оборудование для клиник [url=https://xn—-7sbcejdfbbzea0axlidbbn0a0b5a8f.xn--p1ai]оборудование для клиник[/url] .
oborydovanie medicinskoe_oxsi
6 Oct 25 at 4:23 am
Gyorsabban gyógyultam, és kevesebb fájdalmat éreztem
Hondrolife ízületekhez
Hondrolife ízületekhez
6 Oct 25 at 4:26 am
усиление грунтов [url=https://privetsochi.ru/blog/realty_sochi/93972.html/]privetsochi.ru/blog/realty_sochi/93972.html[/url] .
ysilenie gryntov_zmSr
6 Oct 25 at 4:27 am
What’s up i am kavin, its my first occasion to commenting anyplace,
when i read this piece of writing i thought i could also make comment due to this brilliant article.
Blackridge Markdex Review
6 Oct 25 at 4:27 am
поставщик медицинского оборудования [url=xn—-7sbcejdfbbzea0axlidbbn0a0b5a8f.xn--p1ai]xn—-7sbcejdfbbzea0axlidbbn0a0b5a8f.xn--p1ai[/url] .
oborydovanie medicinskoe_rvsi
6 Oct 25 at 4:28 am
где можно купить диплом техникум [url=https://frei-diplom8.ru/]где можно купить диплом техникум[/url] .
Diplomi_rvsr
6 Oct 25 at 4:28 am
купить диплом специалиста [url=www.rudik-diplom10.ru/]купить диплом специалиста[/url] .
Diplomi_xcSa
6 Oct 25 at 4:29 am
как купить диплом техникума отзывы [url=http://www.frei-diplom10.ru]как купить диплом техникума отзывы[/url] .
Diplomi_btEa
6 Oct 25 at 4:29 am
Very shortly this website will be famous amid all
blogging users, due to it’s good articles
VolksMark Erfahrungen
6 Oct 25 at 4:29 am