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!
Сколько стоит обработка от клопов для квартиры? Интересуют цены.
дезинфекция квартир
KennethceM
26 Oct 25 at 11:24 pm
Viagra generico con pagamento sicuro: pillole per disfunzione erettile – Viagra generico con pagamento sicuro
RandySkync
26 Oct 25 at 11:24 pm
kraken market
кракен ios
Henryamerb
26 Oct 25 at 11:25 pm
После обработка от тараканов стоимость дом безопасный для детей.
дезинфекция складов
KennethceM
26 Oct 25 at 11:25 pm
наркологический анонимный центр [url=https://narkologicheskaya-klinika-23.ru]https://narkologicheskaya-klinika-23.ru[/url] .
narkologicheskaya klinika_tpet
26 Oct 25 at 11:26 pm
I constantly emailed this webpage post page to all my friends, for the reason that if like to read it after that my friends will too.
electric cat water dispenser
26 Oct 25 at 11:26 pm
I am no longer positive where you’re getting your info,
but good topic. I must spend a while finding out much more or working out more.
Thank you for fantastic information I used to be in search of this
info for my mission.
Visit my web page; zinnat02
zinnat02
26 Oct 25 at 11:26 pm
наркологическая клиника город [url=https://narkologicheskaya-klinika-24.ru/]https://narkologicheskaya-klinika-24.ru/[/url] .
narkologicheskaya klinika_wxSr
26 Oct 25 at 11:28 pm
simply click the up coming web site
PHP hook, building hooks in your application – Sjoerd Maessen blog at Sjoerd Maessen blog
simply click the up coming web site
26 Oct 25 at 11:28 pm
https://sites.google.com/view/1xbet-promo-code-no-depositz/home
Michaelhes
26 Oct 25 at 11:29 pm
birxbet giri? [url=https://1xbet-17.com/]1xbet-17.com[/url] .
1xbet_pvpl
26 Oct 25 at 11:31 pm
kraken tor
kraken РФ
Henryamerb
26 Oct 25 at 11:32 pm
Расташоп
Расташоп
26 Oct 25 at 11:33 pm
kraken ссылка
kraken ios
Henryamerb
26 Oct 25 at 11:33 pm
диплом техникума купить в тольятти [url=http://www.frei-diplom10.ru]диплом техникума купить в тольятти[/url] .
Diplomi_jkEa
26 Oct 25 at 11:34 pm
медтехника [url=https://medicinskaya-tehnika.ru/]medicinskaya-tehnika.ru[/url] .
medicinskaya tehnika_ywEi
26 Oct 25 at 11:34 pm
Viagra utan läkarbesök [url=https://mannensapotek.com/#]billig Viagra Sverige[/url] Viagra utan läkarbesök
Davidduese
26 Oct 25 at 11:35 pm
медоборудование [url=http://medicinskoe–oborudovanie.ru]медоборудование[/url] .
medicinskoe oborydovanie_bnei
26 Oct 25 at 11:35 pm
Ищу уничтожение тараканов в общежитии с выездом в область.
профессиональная дератизация
KennethceM
26 Oct 25 at 11:35 pm
kraken вход
kraken vk4
Henryamerb
26 Oct 25 at 11:38 pm
1xbet tr giri? [url=http://1xbet-17.com/]http://1xbet-17.com/[/url] .
1xbet_yepl
26 Oct 25 at 11:39 pm
What’s up, yup this paragraph is in fact nice and I have learned lot of things from it about blogging. thanks.
https://fusioncreations.co.uk/fribet-melbet-2025-obzor-bonusov-i-vyigryshej/
IsmaelNek
26 Oct 25 at 11:40 pm
медицинская техника [url=https://medicinskaya-tehnika.ru/]медицинская техника[/url] .
medicinskaya tehnika_pbEi
26 Oct 25 at 11:40 pm
Its not my first time to pay a quick visit this web site,
i am browsing this web page dailly and get pleasant facts from here daily. https://playarealty.com/author/rosslyle969821/
купить аттестаты за 11 класс недорого
26 Oct 25 at 11:41 pm
Superb site you have here but I was wanting to know if you knew of any discussion boards that cover the same topics discussed here?
I’d really like to be a part of online community where
I can get advice from other knowledgeable people that share the same interest.
If you have any suggestions, please let me know.
Many thanks!
web page
26 Oct 25 at 11:42 pm
1xbet g?ncel giri? [url=https://1xbet-17.com]1xbet g?ncel giri?[/url] .
1xbet_lipl
26 Oct 25 at 11:42 pm
наркологическая клиника в москве [url=www.narkologicheskaya-klinika-23.ru]www.narkologicheskaya-klinika-23.ru[/url] .
narkologicheskaya klinika_kvet
26 Oct 25 at 11:44 pm
kraken вход
кракен vpn
Henryamerb
26 Oct 25 at 11:44 pm
оборудование медицинское [url=http://medicinskoe–oborudovanie.ru]оборудование медицинское[/url] .
medicinskoe oborydovanie_hxei
26 Oct 25 at 11:48 pm
Обработка уничтожение черных тараканов эффективная, рекомендую.
обработка от запахов
KennethceM
26 Oct 25 at 11:48 pm
With havin so much content do you ever run into any issues of plagorism or copyright infringement?
My blog has a lot of completely unique content I’ve either authored myself or outsourced but it seems
a lot of it is popping it up all over the web without
my agreement. Do you know any ways to help reduce content from being ripped off?
I’d certainly appreciate it.
### Article 5: Matching Tungsten Sets: Unity in Every
Curve and Finish
Nothing symbolizes partnership like matching tungsten wedding ring sets, where shared designs forge
visible bonds. Tungstenwedding.com curates these
from $99.98 per ring, in complementary styles—his 6mm brushed, hers 4mm polished—for harmonious aesthetics that scream “team.”
Tungsten carbide’s uniformity allows perfect matches:
same widths, colors (black IP or rose gold), or motifs like Celtic knots.
Inlays synchronize too—wood for both evokes intertwined
roots. Hypoallergenic and durable, sets endure parallel paths, from elopements to family adventures.
Customization seals the deal: dual engravings of intertwined initials.
Affordable luxury means no skimping—full sets
under $400, with free shipping.
For diverse couples, options like slim women’s stacks with bold men’s domed promote equality.
Care is effortless, though brittleness advises against drops.
Matching sets transcend trends, becoming family lore—passed to
kids as unity’s blueprint. In tungsten’s steadfast gleam, they remind: love matches in strength and style, curved together for life.
(Word count: 498)
### Article 6: Tungsten vs. Traditional Metals: A Head-to-Head Comparison
Tungsten wedding rings challenge gold and platinum’s throne, offering superior practicality without pomp.
At $99.98 on tungstenwedding.com, tungsten carbide outshines gold’s $500+
softness—Mohs 9 vs. 2.5—resisting scratches for lifetimes, while gold
bends easily.
Platinum’s hypoallergenic allure matches tungsten’s, but at triple
the cost, it tarnishes subtly; tungsten stays eternally bright, corrosion-free.
Both suit active wear, yet tungsten’s lightness belies density, feeling premium without heft.
Aesthetics? Tungsten’s finishes—brushed, hammered—modernize; gold’s warmth traditionalizes.
Inlays give tungsten edge in personalization, unavailable in pure platinum.
Resale favors precious metals, but tungsten’s low-maintenance wins for
daily vows. Free returns ease trials.
Ultimately, tungsten democratizes durability: affordable, unbreakable
symbols for real-world romance, proving strength needn’t cost a
fortune. (Word count: 502)
|rings|mens rings|womens rings|carbide rings|custom rings|engraved rings|tungsten carbide|tungsten wedding rings|tungsten wedding bands|tungsten beveled|tungsten black|tungsten brushed|tungsten celtic|tungsten classic| tungsten gold| tungsten grooved|tungsten lord of|tungsten mens|tungsten matching|tungsten women|tungsten religious|customized tungsten rings|engraved tungsten rings|tungsten wedding band|tungsten wedding rings|wedding band tungsten|tungsten wedding bands|wedding bands tungsten|wedding
rings tungsten|tungsten wedding ring|tungsten carbide wedding bands|tungsten carbide wedding
rings|wedding ring tungsten|tungsten carbide womens wedding bands|women’s tungsten carbide wedding bands|custom tungsten wedding band|womens tungsten wedding rings|tungsten for wedding band}
|rings|mens rings|womens rings|carbide rings|custom rings|engraved rings|tungsten carbide|tungsten wedding rings|tungsten wedding bands|tungsten beveled|tungsten black|tungsten brushed|tungsten celtic|tungsten classic| tungsten gold| tungsten grooved|tungsten lord
of|tungsten mens|tungsten matching|tungsten women|tungsten religious|customized tungsten rings|engraved tungsten rings|tungsten wedding band|tungsten wedding rings|wedding band
tungsten|tungsten wedding bands|wedding bands tungsten|wedding rings tungsten|tungsten wedding ring|tungsten carbide wedding bands|tungsten carbide
wedding rings|wedding ring tungsten|tungsten carbide womens wedding bands|women’s tungsten carbide
wedding bands|custom tungsten wedding band|womens tungsten wedding
rings|tungsten for wedding band}
tungsten beveled custom rings
26 Oct 25 at 11:50 pm
кракен клиент
кракен Россия
Henryamerb
26 Oct 25 at 11:52 pm
кракен ссылка
кракен ios
Henryamerb
26 Oct 25 at 11:52 pm
kraken qr code
kraken tor
JamesDaync
26 Oct 25 at 11:53 pm
[url=https://promodj.com/zenitbet/tracks/7801690/Bonus_Melbet_pri_registracii_i_drugie_bonusi_i_akcii_Melbet]мелбет бонус при регистрации[/url] даёт тебе фрибет и процент на первый деп без драмы. Всё по-честному: никаких «мы уточним правила позже». Просто регистрируешься, вводишь промокод — и бонус на счету. Отличный способ протестировать платформу без риска. Для новичков — must, для опытных — приятный плюс. Не упусти — это твой законный стартовый boost.
LeazovTig
26 Oct 25 at 11:56 pm
kraken android
kraken РФ
JamesDaync
26 Oct 25 at 11:57 pm
кракен 2025
кракен vk4
Henryamerb
26 Oct 25 at 11:57 pm
1xbet spor bahislerinin adresi [url=www.1xbet-17.com]1xbet spor bahislerinin adresi[/url] .
1xbet_rspl
26 Oct 25 at 11:57 pm
наркологический центр [url=https://narkologicheskaya-klinika-24.ru]наркологический центр[/url] .
narkologicheskaya klinika_iySr
26 Oct 25 at 11:59 pm
медицинская техника [url=http://medicinskaya-tehnika.ru]медицинская техника[/url] .
medicinskaya tehnika_xmEi
26 Oct 25 at 11:59 pm
наркологический анонимный центр [url=http://narkologicheskaya-klinika-23.ru/]http://narkologicheskaya-klinika-23.ru/[/url] .
narkologicheskaya klinika_vyet
27 Oct 25 at 12:00 am
наркология лечение [url=https://www.narkologicheskaya-klinika-23.ru]https://www.narkologicheskaya-klinika-23.ru[/url] .
narkologicheskaya klinika_bret
27 Oct 25 at 12:03 am
kraken СПб
кракен ios
Henryamerb
27 Oct 25 at 12:03 am
Ресторан чистый после уничтожение тараканов в общежитии.
дезинфекция в пищевом производстве
KennethceM
27 Oct 25 at 12:04 am
магазин напольных покрытий Ламинат, несомненно, является одним из самых популярных и доступных видов напольных покрытий. Он представляет собой многослойную конструкцию на основе древесноволокнистой плиты высокой плотности (HDF), с декоративным слоем, имитирующим текстуру дерева, камня или плитки, и защитным верхним слоем, обеспечивающим устойчивость к истиранию и механическим повреждениям. Ламинат привлекает своей простотой укладки, разнообразием дизайнов и относительно невысокой ценой, что делает его идеальным выбором для жилых помещений с умеренной нагрузкой. Однако, следует учитывать, что ламинат менее устойчив к влаге, чем, например, керамическая плитка, и требует бережного ухода.
SteveVed
27 Oct 25 at 12:04 am
После дезинфекция запах исчез, дом свежий!
уничтожение тараканов цена
KennethceM
27 Oct 25 at 12:05 am
оборудование медицинское [url=www.medicinskoe–oborudovanie.ru]оборудование медицинское[/url] .
medicinskoe oborydovanie_mkei
27 Oct 25 at 12:06 am
Profitez d’une offre 1xBet : beneficiez un bonus de 100% pour l’inscription jusqu’a 130€. Renforcez votre solde facilement en placant des paris avec un multiplicateur de cinq fois. Le code bonus est valide tout au long de l’annee 2026. Activez cette offre en rechargant votre compte des 1€. Decouvrez cette offre exclusive sur ce lien > https://www.atrium-patrimoine.com/wp-content/artcls/?code_promo_196.html.
ThomasChiff
27 Oct 25 at 12:08 am
kraken vk4
кракен Россия
Henryamerb
27 Oct 25 at 12:11 am
частная наркологическая клиника в москве анонимное [url=www.narkologicheskaya-klinika-24.ru]www.narkologicheskaya-klinika-24.ru[/url] .
narkologicheskaya klinika_hfSr
27 Oct 25 at 12:11 am