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!
Blue Pharma: sildenafil citrate 100 mg – viagra générique efficace
Maliknaimi
3 Sep 25 at 9:39 pm
Hurrah! At last I got a website from where I can in fact obtain useful facts regarding my study
and knowledge.
رشته های با سوابق تحصیلی تجربی ۱۴۰۴
3 Sep 25 at 9:44 pm
For newest news you have to pay a quick visit world-wide-web and on the web I found
this web site as a best website for most up-to-date updates.
آخرین رتبه قبولی مامایی دانشگاه آزاد ۱۴۰۴
3 Sep 25 at 9:45 pm
Pretty nice post. Ι just srumbled սpon yoսr weblog аnd wished
to ѕay thаt I’vе truly enjoyed browsing your blog posts.
Ιn any cɑse Ӏ’ll be subscribing tο үօur rss feed and I hhope үou wrіte agаin vdry sοon!
Αlso visit myy web site – https://www.letmejerk.com
https://www.letmejerk.com
3 Sep 25 at 9:48 pm
Welcome to https://blevuine.com/, your ultimate financial partner for small businesses. Our company provides advanced financial tools designed to simplify your financial operations and support your business expansion. From credit lines to invoice factoring, Bluevine delivers the flexible financing your business needs. Access to your account is through the Bluevine login portal, where you can safely and efficiently manage all your financial needs. Join thousands of satisfied entrepreneurs who trust Bluevine to advance their business.
LewisGuatt
3 Sep 25 at 9:50 pm
психиатр на дом для пожилого
psikhiatr-moskva004.ru
получить консультацию психиатра
psihiatrmskNeT
3 Sep 25 at 9:52 pm
В Химках многие уже обращались за помощью в Stop Alko — здесь умеют мягко и безопасно вывести из запоя, сохранив здоровье пациента.
Получить больше информации – [url=https://vyvod-iz-zapoya-himki13.ru/]анонимный вывод из запоя[/url]
StewartNam
3 Sep 25 at 9:54 pm
Моды на игры для Android дают новые функции, расширяют функционал.
Дают доступ к платным функциям, разблокировать новые
уровни и ресурсы, и пробовать новые режимы, в стандартных апках нет.
Особенно востребованы скачать моды для андроид, которые позволяют наслаждаться
геймплеем в любом месте, без интернета,
удобно в дороге. Бесконечные ресурсы, интегрированные мод меню и специально подготовленные мод
apk дают игроку полный контроль над процессом, настраивать под себя.
Геймплей становится проще и интереснее, и делает процесс индивидуальным.
Для игрока моды — это больше, чем установка, это шанс
получить больше возможностей и удовольствия.
скачать моды для андроид
3 Sep 25 at 9:55 pm
E2BET پاکستان میں خوش آمدید – آپ کی جیت، مکمل طور
پر ادا کی جاتی ہے۔ پرکشش بونس کا لطف اٹھائیں، دلچسپ
گیمز کھیلیں، اور ایک منصفانہ اور آرام دہ آن لائن بیٹنگ
کا تجربہ کریں۔ ابھی رجسٹر کریں!
E2BET پاکستان
3 Sep 25 at 9:56 pm
This post is really a good one it helps new internet people,
who are wishing in favor of blogging.
Also visit my web-site: 토토피아
토토피아
3 Sep 25 at 9:58 pm
http://www.pageorama.com/?p=ryubebyu
Rogerfef
3 Sep 25 at 10:02 pm
поисковое продвижение москва профессиональное продвижение сайтов [url=http://www.internet-agentstvo-prodvizhenie-sajtov-seo.ru]http://www.internet-agentstvo-prodvizhenie-sajtov-seo.ru[/url] .
internet agentstvo prodvijenie saitov seo_bhot
3 Sep 25 at 10:03 pm
Write more, thats all I have to say. Literally, it seems
as though you relied on the video to make your point.
You definitely know what youre talking about, why waste your intelligence on just posting videos to your
site when you could be giving us something informative to read?
tea/coffee making facilities
3 Sep 25 at 10:04 pm
Its such as you learn my thoughts! You seem to grasp
a lot approximately this, like you wrote the book in it or something.
I think that you could do with a few p.c. to pressure the message house a bit, however
instead of that, this is fantastic blog. A fantastic read.
I’ll definitely be back.
https://bom88.ru.com
3 Sep 25 at 10:04 pm
I just couldn’t leave your site before suggesting that I
actually enjoyed the usual information an individual provide in your visitors?
Is gonna be back frequently to check out new posts
Driving school Leicester
3 Sep 25 at 10:06 pm
https://bs-bsme.at
DanielSoumn
3 Sep 25 at 10:07 pm
заказать анализ сайта [url=internet-agentstvo-prodvizhenie-sajtov-seo.ru]заказать анализ сайта[/url] .
internet agentstvo prodvijenie saitov seo_ljot
3 Sep 25 at 10:13 pm
Attractive section of content. I just stumbled upon your weblog and in accession capital to claim that
I acquire in fact enjoyed account your blog posts. Anyway I will be subscribing for your augment or even I achievement you get entry to constantly quickly.
порно жесткий анал
3 Sep 25 at 10:15 pm
диплом купить харьков цена [url=http://educ-ua2.ru/]диплом купить харьков цена[/url] .
Diplomi_yqOt
3 Sep 25 at 10:15 pm
J’apprecie enormement 1win Casino, il offre une aventure palpitante. Il y a une multitude de titres varies, proposant des jeux de table classiques et raffines. Les agents sont toujours prets a aider, repondant rapidement. Les paiements sont fluides et fiables, bien que plus de tours gratuits seraient un plus. Globalement, 1win Casino vaut pleinement le detour pour les joueurs en quete de sensations fortes ! En bonus l’interface est fluide et intuitive, renforce l’immersion totale.
1win casino online|
kiki4zef
3 Sep 25 at 10:21 pm
продвижение в google [url=www.internet-agentstvo-prodvizhenie-sajtov-seo.ru]www.internet-agentstvo-prodvizhenie-sajtov-seo.ru[/url] .
internet agentstvo prodvijenie saitov seo_tkot
3 Sep 25 at 10:22 pm
Quality articles is the main to be a focus for the users to go to see the website, that’s what this website is
providing.
شرایط پشت کنکور ماندن پسران
3 Sep 25 at 10:28 pm
швейное производство на заказ [url=https://nitkapro.ru]https://nitkapro.ru[/url] .
shveinoe proizvodstvo_qhea
3 Sep 25 at 10:30 pm
В-третьих, реабилитация и ресоциализация. Успешное лечение требует не только устранения физической зависимости. Мы акцентируем внимание на восстановлении социальных связей, улучшении психоэмоционального состояния и формировании новых интересов. Программа включает как групповые, так и индивидуальные занятия, что позволяет пациентам обрести уверенность в себе.
Подробнее можно узнать тут – http://алко-лечебница.рф
TerryTic
3 Sep 25 at 10:36 pm
Aloha King Elvis X-Mas Edition играть в Монро
Louisdut
3 Sep 25 at 10:36 pm
швейное производство полного цикла [url=https://nitkapro.ru]https://nitkapro.ru[/url] .
shveinoe proizvodstvo_goea
3 Sep 25 at 10:36 pm
Hello! I know this is kinda off topic however I’d figured I’d ask.
Would you be interested in exchanging links or maybe guest writing a blog
article or vice-versa? My site addresses a lot of the same subjects as yours
and I think we could greatly benefit from each other. If
you are interested feel free to send me an e-mail. I look forward to hearing
from you! Excellent blog by the way!
Look into my blog 스포츠 배팅 분석 토토피아
스포츠 배팅 분석 토토피아
3 Sep 25 at 10:37 pm
J’adore a fond Betzino Casino, il offre une plongee dans un univers palpitant. Le catalogue est incroyablement riche, incluant des slots de pointe de NetEnt et Pragmatic Play. Le support est ultra-reactif via chat en direct de 10h a 23h, offrant des solutions claires et utiles. Le processus de retrait est simple et fiable avec un maximum de 5000 € par semaine, neanmoins les offres pourraient etre plus genereuses. Pour conclure, Betzino Casino ne decoit jamais pour les adeptes de sensations fortes ! Ajoutons que la navigation est intuitive sur mobile via iOS/Android, ajoute une touche de dynamisme a l’experience.
betzino casino bonus|
Marvinmay3zef
3 Sep 25 at 10:39 pm
I’m not sure exactly why but this website is loading incredibly slow for me.
Is anyone else having this problem or is it a problem on my end?
I’ll check back later and see if the problem still exists.
บาคาร่า 168
3 Sep 25 at 10:39 pm
глубокий комлексный аудит сайта [url=www.poiskovoe-prodvizhenie-sajta-v-internete-moskva.ru]www.poiskovoe-prodvizhenie-sajta-v-internete-moskva.ru[/url] .
poiskovoe prodvijenie saita v internete moskva_xwMa
3 Sep 25 at 10:40 pm
This post is really a good one it helps new the web viewers, who are wishing for blogging.
Here is my webpage – 토토가족방
토토가족방
3 Sep 25 at 10:40 pm
J’apprecie enormement Betify Casino, c’est une veritable plongee dans un univers palpitant. Les options de jeu sont riches et diversifiees, proposant des jeux de table classiques et elegants. Le support est ultra-reactif et professionnel, joignable 24/7. Les transactions sont parfaitement protegees, cependant les bonus pourraient etre plus frequents. Pour conclure, Betify Casino vaut pleinement le detour pour les joueurs en quete d’adrenaline ! En bonus le design est visuellement percutant, ce qui amplifie le plaisir de jouer.
betify se connecter|
Phillipiner6zef
3 Sep 25 at 10:43 pm
фабрика по пошиву [url=https://nitkapro.ru]https://nitkapro.ru[/url] .
shveinoe proizvodstvo_ksea
3 Sep 25 at 10:46 pm
фабрика по пошиву [url=www.nitkapro.ru]www.nitkapro.ru[/url] .
shveinoe proizvodstvo_xjea
3 Sep 25 at 10:49 pm
поисковое продвижение москва профессиональное продвижение сайтов [url=poiskovoe-prodvizhenie-sajta-v-internete-moskva.ru]poiskovoe-prodvizhenie-sajta-v-internete-moskva.ru[/url] .
poiskovoe prodvijenie saita v internete moskva_wpMa
3 Sep 25 at 10:52 pm
https://bs2besd.cc
DanielSoumn
3 Sep 25 at 10:53 pm
купить свидетельство браке киев [url=educ-ua2.ru]educ-ua2.ru[/url] .
Diplomi_csOt
3 Sep 25 at 10:59 pm
Excellent beat ! I would like to apprentice even as you amend your web site, how coulld i
subscribe for a blog site? The account aided mee a acceptable
deal. I were a little bit familiar of this your broadcast offered vibrant transoarent idea
Marita
3 Sep 25 at 11:02 pm
Hello, i think that i saw you visited my website so i came
to “return the favor”.I’m attempting to find things to improve my website!I suppose its ok to use some
of your ideas!!
ปั้มยอดวิว
3 Sep 25 at 11:04 pm
บทความนี้ อ่านแล้วรู้สึกว่าได้มุมมองใหม่ ครับ
ผม ไปเจอรายละเอียดของ ข้อมูลเพิ่มเติม
ลองเข้าไปอ่านได้ที่ สล็อตเว็บตรง
น่าจะเป็นประโยชน์กับหลายคน
มีการเรียบเรียงที่อ่านแล้วลื่นไหล
ขอบคุณที่แชร์ ข้อมูลที่น่าอ่าน นี้
และหวังว่าจะมีข้อมูลใหม่ๆ มาแบ่งปันอีก
สล็อตเว็บตรง
3 Sep 25 at 11:04 pm
комплексное продвижение сайтов москва [url=www.internet-agentstvo-prodvizhenie-sajtov-seo.ru/]комплексное продвижение сайтов москва[/url] .
internet agentstvo prodvijenie saitov seo_bjot
3 Sep 25 at 11:06 pm
Pretty! This was an incredibly wonderful article.
Thanks for supplying this info.
Anri Okita
3 Sep 25 at 11:09 pm
предприятие по пошиву одежды [url=https://www.nitkapro.ru]https://www.nitkapro.ru[/url] .
shveinoe proizvodstvo_qnea
3 Sep 25 at 11:09 pm
I’m excited to uncover this website. I need
to to thank you for your time due to this wonderful read!!
I definitely liked every part of it and i also have you saved as
a favorite to check out new things on your site.
دانشگاه پردیس خودگردان کرمان
3 Sep 25 at 11:09 pm
сделать аудит сайта цена [url=poiskovoe-prodvizhenie-sajta-v-internete-moskva.ru]poiskovoe-prodvizhenie-sajta-v-internete-moskva.ru[/url] .
poiskovoe prodvijenie saita v internete moskva_peMa
3 Sep 25 at 11:12 pm
поисковое продвижение сайта в интернете москва [url=http://www.internet-agentstvo-prodvizhenie-sajtov-seo.ru]поисковое продвижение сайта в интернете москва[/url] .
internet agentstvo prodvijenie saitov seo_jhot
3 Sep 25 at 11:13 pm
производство и пошив одежды [url=http://nitkapro.ru/]http://nitkapro.ru/[/url] .
shveinoe proizvodstvo_yfea
3 Sep 25 at 11:15 pm
раскрутка сайта москва [url=internet-agentstvo-prodvizhenie-sajtov-seo.ru]раскрутка сайта москва[/url] .
internet agentstvo prodvijenie saitov seo_zrot
3 Sep 25 at 11:17 pm
https://trentonbdpi267.bearsfanteamshop.com/how-to-apply-for-the-2025-national-countertop-contractor-ranking
Every homeowner dreams of having a stunning countertop that enhances their kitchen or bathroom.
Did you know that in 2025, only around 2,000 companies earned a spot in the Top Countertop Contractors Ranking out of 10,000+ evaluated? That’s because at we don’t just accept anyone.
Our ranking is transparent, updated regularly, and built on 21+ criteria. These include ratings from Google, Yelp, and other platforms, affordability, communication, and project quality. On top of that, we conduct countless phone calls and over two thousand estimate requests through our mystery shopper program.
The result is a benchmark that benefits both property owners and contractors. Homeowners get a proven way to choose contractors, while listed companies gain credibility, SEO visibility, and even direct client leads.
The Top 500 Awards spotlight categories like Veteran Companies, Rising Stars, and Value Leaders. Winning one of these honors means a company has achieved rare credibility in the industry.
If you’re looking for a countertop contractor—or your company wants to be listed among the best—this site is where trust meets visibility.
JuniorShido
3 Sep 25 at 11:17 pm
Hiya! Quick question that’s entirely off topic. Do you know how to make your site mobile friendly?
My web site looks weird when browsing from my iphone. I’m
trying to find a theme or plugin that might be able to
fix this problem. If you have any recommendations, please share.
With thanks!
car accident doctor nearby
3 Sep 25 at 11:18 pm