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!
Эта информационная заметка содержит увлекательные сведения, которые могут вас удивить! Мы собрали интересные факты, которые сделают вашу жизнь ярче и полнее. Узнайте нечто новое о привычных аспектах повседневности и откройте для себя удивительный мир информации.
Провести детальное исследование – https://www.art-de-lhair.fr/produit/seche-cheveux-flight-ghd
ArnoldMaymn
5 Sep 25 at 8:07 am
If you desire to obtain a good deal from this paragraph then you have to apply
such strategies to your won blog.
Feel free to visit my website Plissee nach Maß
Plissee nach Maß
5 Sep 25 at 8:11 am
Екб
Brandongal
5 Sep 25 at 8:13 am
Эта публикация завернет вас в вихрь увлекательного контента, сбрасывая стереотипы и открывая двери к новым идеям. Каждый абзац станет для вас открытием, полным ярких примеров и впечатляющих достижений. Подготовьтесь быть вовлеченными и удивленными каждый раз, когда продолжите читать.
Углубить понимание вопроса – https://lpw.economic-literacy.eu/forums/topic/youre-welcome
Phillipler
5 Sep 25 at 8:15 am
подключение интернета по адресу
inernetvkvartiru-nizhnij-novgorod006.ru
провайдеры по адресу дома
internetelini
5 Sep 25 at 8:15 am
Your style is very unique compared to other folks I’ve read stuff from.
Many thanks for posting when you have the opportunity,
Guess I will just bookmark this site.
My blog post: Plissee auf Maß
Plissee auf Maß
5 Sep 25 at 8:16 am
скачать мостбет кз [url=https://mostbet4128.ru]https://mostbet4128.ru[/url]
mostbet_kg_yrot
5 Sep 25 at 8:16 am
Awesome issues here. I’m very satisfied to look your article.
Thanks so much and I’m looking ahead to contact you. Will you kindly drop me a mail?
claritox pro buy
5 Sep 25 at 8:19 am
Публикация приглашает вас исследовать неизведанное — от древних тайн до современных достижений науки. Вы узнаете, как случайные находки превращались в революции, а смелые мысли — в новые эры человеческого прогресса.
Почему это важно? – http://4-storm.com/pre-sale-on-indiegogo-is-ready-to-start-the-indemand-program-is-online
Nathansar
5 Sep 25 at 8:20 am
купить диплом в кировограде [url=http://www.educ-ua3.ru]http://www.educ-ua3.ru[/url] .
Diplomi_bmki
5 Sep 25 at 8:20 am
купить старый диплом техникума киев [url=educ-ua20.ru]купить старый диплом техникума киев[/url] .
Diplomi_duEn
5 Sep 25 at 8:25 am
Этот интересный отчет представляет собой сборник полезных фактов, касающихся актуальных тем. Мы проанализируем данные, чтобы вы могли сделать обоснованные выводы. Читайте, чтобы узнать больше о последних трендах и значимых событиях!
Полная информация здесь – http://www.cuim-chi.ru
HaroldGop
5 Sep 25 at 8:26 am
Menurut saya, artikel ini sangat informatif karena membahas
KUBET dan Situs Judi Bola Terlengkap dengan cara yang sederhana namun jelas.
Tidak semua orang bisa menjelaskan topik
ini secara detail, tetapi penulis berhasil melakukannya.
Hasilnya, pembaca dari berbagai kalangan dapat memahami isi artikel dengan mudah.
Yang saya sukai adalah cara penulis menyusun informasi
secara runtut.
KUBET dan Situs Judi Bola Terlengkap dijelaskan dari sudut pandang yang bermanfaat, bukan hanya sekedar promosi.
Hal ini membuat tulisan terasa lebih berimbang dan memberikan nilai
tambah bagi siapa saja yang membacanya.
Selain konten yang lengkap, gaya bahasa juga nyaman untuk diikuti.
Kalimat yang ringan membuat topik yang biasanya dianggap rumit menjadi mudah dipahami.
Ini merupakan kelebihan yang jarang ditemui pada artikel sejenis.
Bagi saya pribadi, tulisan ini menjadi referensi yang cukup penting.
KUBET dan Situs Judi Bola Terlengkap memang sering saya dengar,
tetapi melalui artikel ini saya mendapatkan penjelasan lebih detail.
Hal ini tentu membantu saya memahami dengan lebih baik.
Saya berharap akan ada lebih banyak artikel seperti ini di masa mendatang.
Konten yang bermanfaat dan berkualitas tinggi pasti akan selalu dicari pembaca.
Terima kasih kepada penulis yang sudah meluangkan waktu untuk menulis artikel ini dengan sangat baik.
Situs Parlay Gacor
5 Sep 25 at 8:27 am
купить диплом о высшем образовании украины [url=https://www.educ-ua20.ru]купить диплом о высшем образовании украины[/url] .
Diplomi_yfEn
5 Sep 25 at 8:29 am
Этот информационный материал собраны данные, которые помогут лучше понять текущие тенденции и процессы в различных сферах жизни. Мы предоставляем четкий анализ, графики и примеры, чтобы информация была не только понятной, но и практичной для принятия решений.
Заходи — там интересно – http://www.jonathancastil.com/archi-2-architect
Robertdance
5 Sep 25 at 8:32 am
We’re a bunch of volunteers and opening a
brand new scheme in our community. Your site provided us with useful info to work on. You’ve
performed an impressive activity and our entire neighborhood will likely be
grateful to you.
My web blog komunitas hiburan online
komunitas hiburan online
5 Sep 25 at 8:32 am
член сломался, секс-кукла, продажа секс-игрушек,
राजा छह, राजा ने पैर फैलाकर, प्लर राजा, ৰাজ্যসমূহৰ ৰজা, গুৰুত্বপূৰ্ণ সঁজুলি বিক্ৰী কৰা
член сломался
5 Sep 25 at 8:32 am
https://fundament-spb.ru/wp-content/news/vegetarianstvo_osnovannoe_na_ekonomicheskih_soobragheniyah.html
https://fundament-spb.ru/wp-content/news/vegetarianstvo_osnovannoe_na_ekonomicheskih_soobragheniyah.html
5 Sep 25 at 8:38 am
купить проведенный диплом кого [url=http://educ-ua15.ru/]купить проведенный диплом кого[/url] .
Diplomi_btmi
5 Sep 25 at 8:38 am
купить диплом легальный [url=http://educ-ua14.ru/]купить диплом легальный[/url] .
Diplomi_llkl
5 Sep 25 at 8:40 am
https://www.grepmed.com/ycydyydica
GerardCig
5 Sep 25 at 8:41 am
Публикация приглашает вас исследовать неизведанное — от древних тайн до современных достижений науки. Вы узнаете, как случайные находки превращались в революции, а смелые мысли — в новые эры человеческого прогресса.
Секреты успеха внутри – https://www.hamedanhaji.ir/%DA%A9%D8%A7%D8%B1%D8%AE%D8%A7%D9%86%D9%87-%D9%87%D8%A7%DB%8C-%D8%AA%D9%88%D9%84%DB%8C%D8%AF%DA%A9%D9%86%D9%86%D8%AF%D9%87-%D8%B3%DB%8C%D9%84%DB%8C%D8%B3
Robertdance
5 Sep 25 at 8:43 am
It’s a pity you don’t have a donate button! I’d certainly donate
to this brilliant blog! I guess for now i’ll settle for book-marking
and adding your RSS feed to my Google account. I look forward to new
updates and will talk about this blog with my Facebook group.
Talk soon!
My page – skin clinic maidenhead
skin clinic maidenhead
5 Sep 25 at 8:46 am
Заказать диплом на заказ можно через официальный сайт компании. [url=http://kizm.flybb.ru/viewtopic.php?f=34&t=1499/]kizm.flybb.ru/viewtopic.php?f=34&t=1499[/url]
Sazrnvn
5 Sep 25 at 8:47 am
В этом обзорном материале представлены увлекательные детали, которые находят отражение в различных аспектах жизни. Мы исследуем непонятные и интересные моменты, позволяя читателю увидеть картину целиком. Погрузитесь в мир знаний и удивительных открытий!
Погрузиться в детали – https://www.keye-hamburg.de/2018/12/09/hello-world
ArnoldMaymn
5 Sep 25 at 8:47 am
Эта публикация дает возможность задействовать различные источники информации и представить их в удобной форме. Читатели смогут быстро найти нужные данные и получить ответы на интересующие их вопросы. Мы стремимся к четкости и доступности материала для всех!
Почему это важно? – https://depostjabar.com/jawa-barat/bodecimi/plt-bupati-bogor-terima-penghargaan-pada-perayaan-hari-pers-nasional-tingkat-jawa-barat-tahun-2023/2
BillyNen
5 Sep 25 at 8:47 am
Continue your journey to our commercial financing page where you’ll find the specialized
solutions you need for your business.
https://www.fotofluido.pl
5 Sep 25 at 8:49 am
В этой статье вы найдете познавательную и занимательную информацию, которая поможет вам лучше понять мир вокруг. Мы собрали интересные данные, которые вдохновляют на размышления и побуждают к действиям. Открывайте новую информацию и получайте удовольствие от чтения!
Смотрите также… – https://sampooranpunjabnews.com/2-persons-arrested-with-illegal-liquor
BillyNen
5 Sep 25 at 8:52 am
Этот информационный материал собраны данные, которые помогут лучше понять текущие тенденции и процессы в различных сферах жизни. Мы предоставляем четкий анализ, графики и примеры, чтобы информация была не только понятной, но и практичной для принятия решений.
Узнать напрямую – http://generalist-blog.com/2016/04/17/maxila-and-tongue-posture
RobertFidge
5 Sep 25 at 8:53 am
купить диплом в одессе [url=educ-ua10.ru]купить диплом в одессе[/url] .
Diplomi_qwKl
5 Sep 25 at 8:57 am
купить диплом киев [url=www.educ-ua20.ru]www.educ-ua20.ru[/url] .
Diplomi_sbEn
5 Sep 25 at 9:01 am
диплом купить реестр [url=www.educ-ua11.ru/]диплом купить реестр[/url] .
Diplomi_cePi
5 Sep 25 at 9:02 am
продвижение сайтов в москве [url=www.kompanii-zanimayushchiesya-prodvizheniem-sajtov.ru/]продвижение сайтов в москве[/url] .
kompanii zanimaushiesya prodvijeniem saitov_wgoi
5 Sep 25 at 9:05 am
Этот текст сочетает в себе элементы познавательного рассказа и аналитической подачи информации. Читатель получает доступ к уникальным данным, которые соединяют прошлое с настоящим и открывают двери в будущее.
Все материалы собраны здесь – https://nncs.es/animate-a-participar-en-las-iv-jornadas-nacionales-de-dano-cerebral-andando-se-hace-el-camino-nncs
Nathansar
5 Sep 25 at 9:06 am
Мы предлагаем вам подробное руководство, основанное на проверенных источниках и реальных примерах. Каждая часть публикации направлена на то, чтобы помочь вам разобраться в сложных вопросах и применить знания на практике.
Почему это важно? – https://sonyah.pro/index.php/en/component/k2/item/7-footer/7-footer?start=130490
Ralphtek
5 Sep 25 at 9:09 am
https://www.brownbook.net/business/54217792/тест-купить-наркотик-соль/
GerardCig
5 Sep 25 at 9:10 am
Si vous êtes un joueur débutant, commencez par des coffres de faible niveau, puis progressez vers des trésors plus difficiles à mesure que vous devenez plus expérimenté.
offshore bookmakers
5 Sep 25 at 9:10 am
Мы предлагаем вам подробное руководство, основанное на проверенных источниках и реальных примерах. Каждая часть публикации направлена на то, чтобы помочь вам разобраться в сложных вопросах и применить знания на практике.
Неизвестные факты о… – https://erdekesblog.com/13-szokatlan-kulsovel-megaldott-szemely-aki-csak-ugy-vonzza-a-tekinteteket
Ralphtek
5 Sep 25 at 9:14 am
Tienduizenden spelers zijn je al voorgegaan en hebben naast free
gokkasten ook met echte credits via zo’n online casino gespeeld.
Je kan hiermee ook gewoon via je eigen bank geld storten.
Inzetten kan op iedere speelautomaat, tafel- en kaartspel, videopoker, live casinospel en Sportsbook.
Je vindt in casino’s op dit platform vaak live speeltafels van providers als Evolution, Authentic Live Gaming, Pragmatic Play Live en Playtech Live.
De gokkasten van ons casino worden ontwikkeld door bekende en populaire game providers.
Voor de punters onder ons met een hoog budget die graag op de limieten willen spelen zoeken we altijd bij iedere bookie uit wat de speellimieten zijn. Ons advies luid: speel alleen de gratis spellen. De Duitse ontwikkelaar maakt nieuwe spellen die goed in elkaar zitten. Je kunt als je een kast nog niet zo goed kent dus ook lekker gratis oefenen totdat je alle spel elementen goed onder de
knie hebt. In het begin nog zonder dat de kast direct winsten kon uitbetalen.
kroon casino
5 Sep 25 at 9:14 am
Купить диплом ВУЗа!
Наша компания предлагаетвыгодно купить диплом, который выполнен на оригинальной бумаге и заверен мокрыми печатями, водяными знаками, подписями. Документ пройдет лубую проверку, даже с применением профессионального оборудования. Решайте свои задачи быстро и просто с нашими дипломами- [url=http://privamaxsecurity.co.ke/employer/aurus-diplomany/]privamaxsecurity.co.ke/employer/aurus-diplomany[/url]
Jariorkoe
5 Sep 25 at 9:15 am
диплом техникума торгового купить [url=http://educ-ua6.ru]http://educ-ua6.ru[/url] .
Diplomi_ozMl
5 Sep 25 at 9:18 am
I could not refrain from commenting. Well written!
web site
5 Sep 25 at 9:18 am
https://praveensaanker.com/art/code_promo_d_inscription_1xbet.html
https://praveensaanker.com/art/code_promo_d_inscription_1xbet.html
5 Sep 25 at 9:22 am
Казино Вавада онлайн давно привлекает внимание игроков.
Здесь проводятся турниры, которые увеличивают интерес.
Бонусные предложения позволяют начинать без вложений.
Разделы с развлечениями поддерживаются ведущими провайдерами.
Создать аккаунт несложно, а использовать промо можно моментально.
Подробности ищите тут: vavada промокод 2025
Danielnig
5 Sep 25 at 9:22 am
Arctic Fish and Cash играть в Кет казино
Georgererry
5 Sep 25 at 9:24 am
Заказать диплом под заказ в Москве вы сможете через сайт компании. [url=http://siciliaoutdoor.org/kupit-diplom-oficialno-i-bez-riska-39/]siciliaoutdoor.org/kupit-diplom-oficialno-i-bez-riska-39[/url]
Sazrayq
5 Sep 25 at 9:25 am
дипломы бывшего ссср купить [url=https://www.educ-ua20.ru]https://www.educ-ua20.ru[/url] .
Diplomi_czEn
5 Sep 25 at 9:26 am
mostbet jonli efir [url=https://mostbet4166.ru]https://mostbet4166.ru[/url]
mostbet_evSr
5 Sep 25 at 9:27 am
Эта информационная заметка содержит увлекательные сведения, которые могут вас удивить! Мы собрали интересные факты, которые сделают вашу жизнь ярче и полнее. Узнайте нечто новое о привычных аспектах повседневности и откройте для себя удивительный мир информации.
Не упусти важное! – https://www.portoforno.com/es/products/famosi-2
RobertFidge
5 Sep 25 at 9:30 am
I am in fact grateful to tһe owner of this
web page wһo has ѕhared this great piece of writіng at at this
time.
Also visit my site – Black zip up
Black zip up
5 Sep 25 at 9:33 am