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://medoborudovanie-postavka.ru/]поставка медицинского оборудования[/url] .
postavka medicinskogo oborydovaniya_vfsn
26 Oct 25 at 4:08 pm
1xbet ?ye ol [url=https://1xbet-13.com]https://1xbet-13.com[/url] .
1xbet_rfKa
26 Oct 25 at 4:10 pm
платная наркологическая клиника в москве [url=https://narkologicheskaya-klinika-23.ru/]narkologicheskaya-klinika-23.ru[/url] .
narkologicheskaya klinika_nwet
26 Oct 25 at 4:10 pm
Viagra genérico online España: farmacia confiable en España – farmacia online para hombres
RandySkync
26 Oct 25 at 4:11 pm
I am curious to find out what blog system you have been using?
I’m having some minor security problems with my latest site and I’d like to
find something more safeguarded. Do you have any suggestions?
gps tracker for pets apple
26 Oct 25 at 4:11 pm
поставщик медоборудования [url=http://medoborudovanie-postavka.ru/]http://medoborudovanie-postavka.ru/[/url] .
postavka medicinskogo oborydovaniya_yrsn
26 Oct 25 at 4:14 pm
visit their website
PHP hook, building hooks in your application – Sjoerd Maessen blog at Sjoerd Maessen blog
visit their website
26 Oct 25 at 4:15 pm
kraken вход
кракен даркнет маркет
JamesDaync
26 Oct 25 at 4:16 pm
Если вы хотите найти информацию о бонусах при регистрации, ознакомьтесь с наши рекомендации о видах вознаграждений; в одном из разделов статьи естественно упомянут промокод на баллы 1xbet для получения приветственного бонуса. Редакция объясняем, как указывать данные при регистрации и какие условия нужно выполнить для отыгрыша.
RobertRak
26 Oct 25 at 4:17 pm
поставщик медицинского оборудования [url=http://www.medoborudovanie-postavka.ru]поставщик медицинского оборудования[/url] .
postavka medicinskogo oborydovaniya_lhsn
26 Oct 25 at 4:17 pm
После санэпидемстанция цены дом безопасный для детей.
обработка от клопов с гарантией
KennethceM
26 Oct 25 at 4:20 pm
наркология лечение [url=http://narkologicheskaya-klinika-24.ru/]http://narkologicheskaya-klinika-24.ru/[/url] .
narkologicheskaya klinika_tqSr
26 Oct 25 at 4:20 pm
После дезинфекция складов дом безопасный для детей.
дезинсекция
KennethceM
26 Oct 25 at 4:21 pm
bahis siteler 1xbet [url=1xbet-14.com]bahis siteler 1xbet[/url] .
1xbet_tcet
26 Oct 25 at 4:22 pm
After I initially commented I seem to have clicked the -Notify me when new comments are added- checkbox and from now
on whenever a comment is added I receive 4 emails with the exact same comment.
There has to be a means you can remove me from that service?
Kudos!
bästa casino online
26 Oct 25 at 4:22 pm
наркологическая помощь [url=narkologicheskaya-klinika-23.ru]narkologicheskaya-klinika-23.ru[/url] .
narkologicheskaya klinika_vpet
26 Oct 25 at 4:22 pm
Goodness, even if establishment гemains atas, mathematics serves ɑs the
decisive subject іn developing confidence rеgarding figures.
Aiyah, primary maths teaches practical implementations including money management, tһսs guarantee your child masters it
гight fгom үoung.
Victoria Junior College cultivates imagination ɑnd leadership, igniting enthusiasms for future development.
Coastal school centers support arts, liberal arts, аnd sciences.
Integrated programs ᴡith alliances provide seamless, enriched education. Service ɑnd international initiatives build caring,
resistant people. Graduates lead ᴡith conviction, attaining exceptional success.
Jurong Pioneer Junior College, developed tһrough the thoughtful merger оf Jurong Junior College ɑnd Pioneer Junior
College, delivers а progressive ɑnd future-oriented education that рuts a special emphasis оn China readiness, worldwide company acumen, and cross-cultural engagement tߋ prepare
trainees for growing in Asia’ѕ vibrant financial landscape.
Thе college’s dual campuses aгe equipped witһ
modern, versatile facilities consisting of specialized commerce simulation гooms,
science innovation laboratories, ɑnd arts ateliers, ɑll developed to foster
ᥙseful skills, creativity, аnd interdisciplinary learning.
Improving academic programs ɑre matched ƅy international cooperations, ѕuch aѕ joint jobs with Chinese universities аnd cultural immersion trips, ᴡhich improve students’
linguistic efficiency аnd international outlook. Ꭺ encouraging and inclusive community environment encourages strength ɑnd leadership development tһrough a broad
variety οf cο-curricular activities, fгom entrepreneurship clubs tо sports teams
tһat promote teamwork and determination.
Graduates of Jurong Pioneer Junior College ɑre exceptionally ԝell-prepared fߋr competitive
professions, embodying tһe values of care, continuous enhancement, ɑnd innovation that specіfy the
organization’ѕ positive values.
Don’t take lightly lah, link a ɡood Junior College ρlus maths excellence to guarantee һigh Ꭺ
Levelps scores ɑnd effortless transitions.
Parents, dread tһe difference hor, mathematics
base is vital at Junior College t᧐ grasping іnformation, essential іn modern tech-driven economy.
Oh man, no matter wһether school is hіgh-end, mathematics
serves аs the critical topic for cultivates pooise іn figures.
Oi oi, Singapore parents, mathematics гemains probably tһе
highly essential primary subject, fostering innovation tһrough challenge-tackling in innovative professions.
Αvoid tаke lightly lah, pair a reputable Junior College ᴡith mathematics proficiency іn order to ensure һigh
А Levels results and smooth сhanges.
Math at A-levels іs liҝe a puzzle; solving іt builds confidence fօr life’s challenges.
Hey hey, Singapore folks, math proves ⅼikely the highly essential
primary subject, promoting imagination f᧐r problem-solving to groundbreaking
careers.
Αlso visit my web-site … list of junior colleges
list of junior colleges
26 Oct 25 at 4:26 pm
Бесплатный рабочий промокод Melbet на сегодня ищет каждый потенциальный клиент компании. Почему? Мало кто откажется от щедрой приветственной награды, позволяющей увеличить сумму первого депозита, заработав до ?9100 бонуса (с 24 апреля бонус увеличился до 50 000). Промокоды – это маркетинговый инструмент, с помощью которого рекламные партнеры букмекера привлекают новых бетторов. Поэтому в современной практике сам букмекер редко распространяет коды, за исключением флагманских акций или раздачи купонов в рамках специальных ивентов. Не все бонусы предполагают наличие рекламного кода. Для активации большинства из них достаточно просто пополнить счет или делать ставки на спорт, получая за это баллы активности. В последующем есть возможность в рамках программы лояльности БК «Мелбет» обменивать баллы на коды для бесплатных ставок (фрибеты) или на реальные денежные средства. Раздобыть промокод Melbet Вы всегда сможете на нашем сайте. При этом Вы можете быть уверенными в том, что это именно актуальное предложение. Также рекомендуем подписаться на информационную рассылку БК, где компания при помощи SMS и почтовых уведомлений держит в курсе событий любителей ставок.
Georgeduh
26 Oct 25 at 4:26 pm
поставщик медоборудования [url=http://medoborudovanie-postavka.ru]http://medoborudovanie-postavka.ru[/url] .
postavka medicinskogo oborydovaniya_wpsn
26 Oct 25 at 4:26 pm
Как купить Фен в Минеральные Водые?Вот, обнаружил сайт https://enlabnk.ru
– цены порадовали, доставка быстрая. Кто-то пробовал у них? Как с качеством продукции?
Stevenref
26 Oct 25 at 4:29 pm
кракен актуальная ссылка
кракен Россия
JamesDaync
26 Oct 25 at 4:29 pm
клиника наркологическая [url=https://narkologicheskaya-klinika-24.ru/]клиника наркологическая[/url] .
narkologicheskaya klinika_szSr
26 Oct 25 at 4:30 pm
поставщик медоборудования [url=https://medoborudovanie-postavka.ru/]medoborudovanie-postavka.ru[/url] .
postavka medicinskogo oborydovaniya_pusn
26 Oct 25 at 4:30 pm
реабилитация зависимых [url=http://narkologicheskaya-klinika-23.ru]http://narkologicheskaya-klinika-23.ru[/url] .
narkologicheskaya klinika_beet
26 Oct 25 at 4:30 pm
1xbet giri? linki [url=https://1xbet-17.com]1xbet giri? linki[/url] .
1xbet_pxpl
26 Oct 25 at 4:31 pm
мед оборудование [url=https://medicinskoe–oborudovanie.ru/]мед оборудование[/url] .
medicinskoe oborydovanie_okei
26 Oct 25 at 4:31 pm
Цены на обработка от блох в доме выросли? Обсудим.
санэпидемстанция круглосуточно
KennethceM
26 Oct 25 at 4:32 pm
Hello, i feel that i saw you visited my weblog so i got here
to go back the prefer?.I’m trying to in finding things to enhance my site!I assume its good enough to make use of a few of your ideas!!
buôn bán nội tạng
26 Oct 25 at 4:33 pm
1xbet resmi giri? [url=http://www.1xbet-17.com]1xbet resmi giri?[/url] .
1xbet_hxpl
26 Oct 25 at 4:35 pm
Ich habe eine Leidenschaft fur Cat Spins Casino, es begeistert mit Dynamik. Das Spieleangebot ist reichhaltig und vielfaltig, mit modernen Slots in ansprechenden Designs. Der Bonus ist wirklich stark. Der Service ist von hochster Qualitat. Der Prozess ist einfach und transparent, dennoch gro?ere Boni waren ein Highlight. In Summe, Cat Spins Casino bietet ein einmaliges Erlebnis. Daruber hinaus ist das Design stilvoll und einladend, das Spielerlebnis bereichert. Ein gro?artiges Bonus die spannenden Community-Aktionen, ma?geschneiderte Vorteile liefern.
Web entdecken|
starwaveik9zef
26 Oct 25 at 4:37 pm
1xbet yeni giri? adresi [url=1xbet-13.com]1xbet yeni giri? adresi[/url] .
1xbet_mkKa
26 Oct 25 at 4:38 pm
buildyourdreamtoday – I recommend checking for an “About Us” page or contact information to understand the site’s legitimacy.
Chi Holshue
26 Oct 25 at 4:39 pm
Ich bin fasziniert von Cat Spins Casino, es entfuhrt in eine Welt voller Spa?. Die Spielauswahl ist beeindruckend, mit dynamischen Wettmoglichkeiten. 100 % bis zu 500 € plus Freispiele. Der Support ist schnell und freundlich. Auszahlungen sind schnell und reibungslos, allerdings mehr Promo-Vielfalt ware toll. In Summe, Cat Spins Casino ist perfekt fur Casino-Liebhaber. Nebenbei die Navigation ist einfach und klar, jede Session unvergesslich macht. Ein hervorragendes Plus die haufigen Turniere fur mehr Spa?, regelma?ige Boni bieten.
Website durchstГ¶bern|
GlobalTigeron6zef
26 Oct 25 at 4:42 pm
поставка медоборудования [url=https://medoborudovanie-postavka.ru/]https://medoborudovanie-postavka.ru/[/url] .
postavka medicinskogo oborydovaniya_sjsn
26 Oct 25 at 4:43 pm
xbet [url=https://1xbet-14.com/]xbet[/url] .
1xbet_iyet
26 Oct 25 at 4:43 pm
наркологическая клиника в москве [url=http://narkologicheskaya-klinika-23.ru]http://narkologicheskaya-klinika-23.ru[/url] .
narkologicheskaya klinika_jcet
26 Oct 25 at 4:44 pm
Нужна дезинфекция квартиры после умершего для автомобиля, посоветуйте.
вызов санэпидемстанции
KennethceM
26 Oct 25 at 4:46 pm
kraken СПб
кракен маркет
JamesDaync
26 Oct 25 at 4:46 pm
1x bet giri? [url=1xbet-17.com]1x bet giri?[/url] .
1xbet_krpl
26 Oct 25 at 4:47 pm
Дай думаю зайду поздороваюсь с мамонтами опасного бизнеса.:hello: купить онлайн мефедрон, экстази, бошки “Кстати Минеру за описание Минус не указал что второй кооператив”
Danielanymn
26 Oct 25 at 4:48 pm
Je ne me lasse pas de Ruby Slots Casino, ca donne une vibe electrisante. Le choix de jeux est tout simplement enorme, incluant des paris sur des evenements sportifs. Il amplifie le plaisir des l’entree. Le suivi est d’une fiabilite exemplaire. Les paiements sont surs et efficaces, de temps en temps des recompenses supplementaires seraient parfaites. En fin de compte, Ruby Slots Casino garantit un amusement continu. De plus le site est rapide et engageant, facilite une experience immersive. A mettre en avant les options de paris sportifs variees, garantit des paiements rapides.
Ouvrir le site|
Swiftpulseok9zef
26 Oct 25 at 4:49 pm
hoki1881
hoki1881
26 Oct 25 at 4:49 pm
trattamento ED online Italia [url=https://mediuomo.com/#]Viagra generico con pagamento sicuro[/url] miglior sito per acquistare Sildenafil online
Davidduese
26 Oct 25 at 4:49 pm
поставка медицинского оборудования [url=medoborudovanie-postavka.ru]поставка медицинского оборудования[/url] .
postavka medicinskogo oborydovaniya_hwsn
26 Oct 25 at 4:53 pm
1xbet resmi sitesi [url=www.1xbet-17.com]1xbet resmi sitesi[/url] .
1xbet_jopl
26 Oct 25 at 4:53 pm
J’adore la vibe de Sugar Casino, ca transporte dans un univers de plaisirs. On trouve une gamme de jeux eblouissante, incluant des options de paris sportifs dynamiques. Il booste votre aventure des le depart. Le service client est de qualite. Les gains arrivent sans delai, mais des bonus plus varies seraient un plus. En conclusion, Sugar Casino est une plateforme qui fait vibrer. En complement le design est moderne et energique, ajoute une vibe electrisante. A signaler les competitions regulieres pour plus de fun, cree une communaute vibrante.
Voir plus|
stormsparkus2zef
26 Oct 25 at 4:53 pm
Thanks very nice blog!
gps tracker for pets apple
26 Oct 25 at 4:54 pm
наркологическая клиника москва [url=https://www.narkologicheskaya-klinika-23.ru]https://www.narkologicheskaya-klinika-23.ru[/url] .
narkologicheskaya klinika_giet
26 Oct 25 at 4:57 pm
клиники наркологические москва [url=http://www.narkologicheskaya-klinika-24.ru]http://www.narkologicheskaya-klinika-24.ru[/url] .
narkologicheskaya klinika_fhSr
26 Oct 25 at 4:58 pm
one x bet [url=http://1xbet-17.com/]one x bet[/url] .
1xbet_impl
26 Oct 25 at 4:58 pm