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=www.pamyatniki-kultury.ru]www.pamyatniki-kultury.ru[/url] .
malishi.online_esEi
7 Aug 25 at 2:49 am
Paybis acts as a innovative crypto‑payment solution, founded in 2014 and headquartered in Warsaw, Poland, now operating in over 180 countries with support for more
than 80–90 cryptocurrencies and handling billions in transaction volume
:contentReference[oaicite:1]index=1. The platform
delivers a desktop & mobile wallet as a service and on‑ramp/off‑ramp API integration options for businesses,
letting users to buy, sell, swap and accept crypto payments effortlessly across traditional and blockchain rails :contentReference[oaicite:2]index=2.
It supports over 50 payment methods including credit/debit cards, e‑wallets, Apple Pay, Google Pay,
local rails like PIX, Giropay, SPEI, bank transfers, etc., across 180 countries and 80+ fiat currencies :
contentReference[oaicite:3]index=3. With a low minimum entry fee—starting at around $2–5 depending on volume—and clear
fee disclosure (typically 2 USD minimum commission and card or e‑wallet fees up to ~4.5–6.5%, plus network fees),
Paybis prides itself on transparent pricing :contentReference[oaicite:4]index=4.
Its hybrid non‑custodial/custodial wallet model,
which splits private keys across multiple parties, ensures on‑chain transparency,
user control, and strong security without needing traditional “proof of reserves” disclosures :
contentReference[oaicite:5]index=5. Paybis is registered as a Money Service Business with FinCEN in the USA,
is VASP‑registered in Poland, and complies with FINTRAC in Canada, enforcing KYC/AML checks for larger transactions while offering optional no‑KYC flow for smaller amounts (under ~$2,
000) in select cases :contentReference[oaicite:6]index=6.
Businesses can integrate Paybis in hours through SDKs and
APIs, access dedicated account managers, and benefit from high authorization rates (~70–95%) and 24/7 multilingual support in over
nine languages :contentReference[oaicite:7]index=7.
Use cases range from wallets, fintechs, marketplaces,
gaming platforms, DeFi services, and global platforms in need of
stablecoin payouts, IBAN‑based settlement, or mass
crypto payouts via Paybis Send or OTC business wallets :contentReference[oaicite:8]index=8.
Although some user‑reported issues have arisen—such as account suspensions without explanation, slow refund processing
in rare scenarios, or payment verification difficulties—overall feedback through Trustpilot and other independent reviews is largely positive with nearly 5‑star ratings thanks to its customer‑friendly design and straightforward crypto onboarding flow :
contentReference[oaicite:9]index=9. Altogether, Paybis delivers a robust, secure,
and flexible crypto payment and wallet solution ideal for businesses wanting
to bridge fiat and crypto with minimal hassle and strong compliance frameworks.
press article
7 Aug 25 at 2:49 am
https://www.rwaq.org/users/jordane488799-20250804233756
Nathanagoky
7 Aug 25 at 2:51 am
купить аттестаты за 11 класс в школе [url=https://arus-diplom24.ru/]https://arus-diplom24.ru/[/url] .
Diplomi_vdKn
7 Aug 25 at 2:54 am
Do you have a spam issue on this site; I also
am a blogger, and I was wanting to know your situation; many of us have developed some nice procedures and we are looking to
exchange methods with other folks, why not shoot
me an e-mail if interested.
Popbem
7 Aug 25 at 2:56 am
Мы гарантируем полное уничтожение тараканов в вашей квартире с оформлением акта выполненных работ: обработка от клопов и тараканов
HaroldUrigE
7 Aug 25 at 3:00 am
Terrific work! This is the type of information that should be shared around the net.
Disgrace on the seek engines for no longer positioning this publish higher!
Come on over and seek advice from my site . Thank you
=)
نحوه محاسبه تراز کنکور
7 Aug 25 at 3:02 am
ventolin brand: AsthmaFree Pharmacy – ventolin prices
Raymondheaps
7 Aug 25 at 3:02 am
После поступления звонка нарколог оперативно выезжает по указанному адресу и прибывает в течение 30–60 минут. Врач незамедлительно приступает к оказанию помощи по четко отработанному алгоритму, состоящему из следующих этапов:
Выяснить больше – https://narcolog-na-dom-voronezh00.ru/vyzov-narkologa-na-dom-voronezh/
Robertcon
7 Aug 25 at 3:07 am
пансионат для пожилых людей
pansionat-msk004.ru
частный пансионат для престарелых
pansimskNeT
7 Aug 25 at 3:07 am
диплом купить в белгороде [url=www.arus-diplom8.ru]диплом купить в белгороде[/url] .
Zakazat diplom ob obrazovanii!_uuol
7 Aug 25 at 3:10 am
It’s really a nice and useful piece of info. I’m happy that you simply shared this useful info
with us. Please stay us up to date like this. Thank you for
sharing.
بيوت شعر
7 Aug 25 at 3:12 am
Услуга
Исследовать вопрос подробнее – https://kapelnica-ot-zapoya-nizhniy-novgorod000.ru/
BruceRet
7 Aug 25 at 3:17 am
В Екатеринбурге решение есть — наркологическая клиника. Здесь помогают людям выйти из запоя без страха и осуждения. Всё анонимно, грамотно и с заботой о каждом пациенте.
Подробнее – [url=https://vyvod-iz-zapoya-ekaterinburg14.ru/]вывод из запоя на дому цена в екатеринбурге[/url]
Arthurgycle
7 Aug 25 at 3:18 am
Wow! At last I got a webpage from where I
be capable of really obtain useful facts regarding my study and knowledge.
ثبت نام آزمون تافل 2025
7 Aug 25 at 3:21 am
После поступления вызова наш нарколог выезжает к пациенту в кратчайшие сроки, прибывая по адресу в пределах 30–60 минут. Специалист начинает процедуру с подробного осмотра и диагностики, измеряя ключевые показатели организма: артериальное давление, частоту пульса, насыщенность кислородом и собирая подробный анамнез.
Исследовать вопрос подробнее – https://narcolog-na-dom-novosibirsk00.ru/narkolog-na-dom-kruglosutochno-novosibirsk
Davidnit
7 Aug 25 at 3:22 am
Женский журнал [url=http://ksusha.online/]http://ksusha.online/[/url] .
ksusha.online_qrpr
7 Aug 25 at 3:25 am
Every weekend i used to pay a quick visit this website,
because i want enjoyment, as this this web site conations
genuinely pleasant funny information too.
Also visit my blog post – Flytning
Flytning
7 Aug 25 at 3:25 am
В таких случаях своевременное обращение за помощью позволяет быстро стабилизировать состояние и предотвратить развитие серьезных осложнений.
Подробнее – [url=https://narcolog-na-dom-voronezh0.ru/]вызов врача нарколога на дом в воронеже[/url]
NormanBax
7 Aug 25 at 3:25 am
I loved as much as you’ll receive carried
out right here. The sketch is attractive, your authored material stylish.
nonetheless, you command get bought 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 increase.
چگونه لاتاری ثبت نام کنیم
7 Aug 25 at 3:25 am
1win promo kod 2025 uz [url=http://1win3065.ru]http://1win3065.ru[/url]
1win_xion
7 Aug 25 at 3:26 am
купить аттестат за 11 класс спб [url=https://arus-diplom24.ru/]купить аттестат за 11 класс спб[/url] .
Diplomi_rkKn
7 Aug 25 at 3:28 am
https://www.band.us/band/99499018/
Nathanagoky
7 Aug 25 at 3:33 am
При поступлении вызова специалисты клиники «АнтиАлко» выезжают на дом в течение 30–60 минут. По прибытии врач проводит комплексную диагностику: измеряет артериальное давление, пульс, уровень кислорода в крови и собирает анамнез, чтобы оценить степень интоксикации. На основе полученных данных формируется индивидуальный план лечения, который включает:
Подробнее – http://vyvod-iz-zapoya-novosibirsk00.ru
Jeremycob
7 Aug 25 at 3:39 am
спб купить диплом [url=www.arus-diplom8.ru]спб купить диплом[/url] .
Kypit diplom VYZa!_quol
7 Aug 25 at 3:40 am
Услуга “Нарколог на дом” в Уфе охватывает широкий спектр лечебных мероприятий, направленных как на устранение токсической нагрузки, так и на работу с психоэмоциональным состоянием пациента. Комплексная терапия включает в себя медикаментозную детоксикацию, корректировку обменных процессов, а также психотерапевтическую поддержку, что позволяет не только вывести пациента из состояния запоя, но и помочь ему справиться с наркотической зависимостью.
Изучить вопрос глубже – [url=https://narcolog-na-dom-ufa000.ru/]нарколог на дом уфа[/url]
Willienic
7 Aug 25 at 3:41 am
chiterskiy.ru [url=www.chiterskiy.ru/]www.chiterskiy.ru/[/url] .
chiterskiy.ru_xxma
7 Aug 25 at 3:42 am
AsthmaFree Pharmacy: AsthmaFree Pharmacy – AsthmaFree Pharmacy
Raymondheaps
7 Aug 25 at 3:45 am
По прибытии нарколог проводит подробный первичный осмотр, собирает анамнез, измеряет жизненно важные показатели и оценивает степень интоксикации. Это позволяет оперативно определить, какие меры необходимы для эффективного вывода из запоя.
Детальнее – [url=https://narcolog-na-dom-ufa00.ru/]нарколог на дом в уфе[/url]
Chrisememe
7 Aug 25 at 3:46 am
IverCare Pharmacy: ivermectin anti inflammatory – ivermectin scabies dosage
Jessieopins
7 Aug 25 at 3:52 am
how much weight can i lose on semaglutide [url=https://glucosmartrx.shop/#]semaglutide tablets side effects[/url] AsthmaFree Pharmacy
Harryinapy
7 Aug 25 at 3:54 am
Когда запой приводит к критическому ухудшению состояния, оперативное лечение становится жизненно необходимым. В Тюмени доступна услуга капельничного вывода из запоя на дому, которая позволяет начать детоксикацию организма незамедлительно и в комфортной для пациента обстановке. Такой формат терапии помогает не только вывести токсины, но и значительно снизить риск осложнений, сохраняя при этом полную конфиденциальность.
Подробнее тут – [url=https://kapelnica-ot-zapoya-tyumen0.ru/]стоимость капельницы от запоя тюмень[/url]
TimothydaW
7 Aug 25 at 3:58 am
FluidCare Pharmacy: lasix furosemide – lasix generic name
Jessieopins
7 Aug 25 at 4:00 am
http://demo2.dz.magcloud.cc/home.php?mod=space&uid=202112&do=profile
http://demo2.dz.magcloud.cc/home.php?mod=space&uid=202112&do=profile
7 Aug 25 at 4:09 am
https://hoo.be/nofcacae
Nathanagoky
7 Aug 25 at 4:16 am
стильные горшки [url=https://www.dizaynerskie-kashpo-sochi.ru]стильные горшки[/url] .
dizainerskie kashpo_oiOn
7 Aug 25 at 4:16 am
I think thе admin of tһіs site is genuinely worқing hard іn support of
his web site, аs here eѵery stuff іs quality based stuff.
Hɑve a ⅼoоk at my webpage :: Jackpot bet
Jackpot bet
7 Aug 25 at 4:27 am
Пациенты, которые выбирают нашу клинику для лечения алкогольного запоя, получают качественную и оперативную помощь, обладающую следующими преимуществами:
Получить дополнительную информацию – [url=https://kapelnica-ot-zapoya-nizhniy-novgorod0.ru/]капельница от запоя на дому цена[/url]
StephenGab
7 Aug 25 at 4:29 am
Hurrah, that’s what I was exploring for, what a information! existing
here at this blog, thanks admin of this site.
Also visit my web site – Flytning
Flytning
7 Aug 25 at 4:30 am
Great items from you, man. I have be mindful your stuff previous to and you are
just too magnificent. I actually like what you’ve obtained here, really like what you’re stating and the
way in which by which you are saying it. You are making it entertaining and you
still care for to keep it smart. I can not wait to learn much more
from you. That is actually a wonderful website.
My blog post Windows 10 Klucz
Windows 10 Klucz
7 Aug 25 at 4:31 am
rybelsus doses for weight loss: AsthmaFree Pharmacy – semaglutide glp 1
Jessieopins
7 Aug 25 at 4:32 am
I have been surfing online more than 3 hours today,
yet I never found any interesting article like yours. It is pretty worth enough for me.
In my opinion, if all web owners and bloggers made good content as you did, the net
will be much more useful than ever before.
Best Casino Live Roulette
7 Aug 25 at 4:38 am
data-vyhoda.online [url=www.data-vyhoda.online/]www.data-vyhoda.online/[/url] .
data-vyhoda.online_yjSr
7 Aug 25 at 4:38 am
Greаt post. I was checkjng continuouѕly thhis blog and I’m impressed!
Very uѕeful informatiоn specifically the last part 🙂
I cade for ѕuch infoгmation much. I was lo᧐kіng for this certain information for a long time.
Thank you and bezt of luck.
Feel fre to visit my page: opcmd.com (Verna)
Verna
7 Aug 25 at 4:39 am
https://ivercarepharmacy.shop/# buy ivermectin for humans online
Jefferyled
7 Aug 25 at 4:40 am
Бизонстрой услуги по аренде спецтехники предоставляет. Предлагаем автокраны, бульдозеры, погрузчики, манипуляторы и другое. Все машины в безупречном состоянии и готовы к немедленному выходу на объект. Думаем, что ваши объекты лучшего заслуживают – выгодных условий и новейшей техники. https://bizonstroy.ru – тут более детальная информация о нас представлена, посмотрите ее уже сегодня. Мы с клиентами нацелены на долгосрочное сотрудничество. Решаем вопросы профессионально и быстро. Обращайтесь к нам и вы довольными останетесь!
refaciDooLa
7 Aug 25 at 4:42 am
data-vyhoda.online [url=https://data-vyhoda.online/]https://data-vyhoda.online/[/url] .
data-vyhoda.online_qfSr
7 Aug 25 at 4:48 am
В Екатеринбурге решение есть — наркологическая клиника. Здесь помогают людям выйти из запоя без страха и осуждения. Всё анонимно, грамотно и с заботой о каждом пациенте.
Подробнее можно узнать тут – [url=https://vyvod-iz-zapoya-ekaterinburg11.ru/]вывод из запоя анонимно[/url]
RichardPoorm
7 Aug 25 at 4:48 am
Чем раньше начато лечение, тем выше вероятность полного восстановления здоровья без тяжёлых последствий для организма и психики. В клинике «Наркосфера» к каждому случаю подходят максимально внимательно и индивидуально.
Подробнее можно узнать тут – [url=https://narkologicheskaya-klinika-balashiha5.ru/]platnaya-narkologicheskaya-klinika[/url]
WilliamaciGh
7 Aug 25 at 4:49 am
Making Nightlife Easy submit (Fay)
Fay
7 Aug 25 at 4:49 am