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!
CanadRx Nexus [url=https://canadrxnexus.shop/#]canadian valley pharmacy[/url] CanadRx Nexus
JamesCoaby
1 Aug 25 at 4:39 pm
купить аттестат за 11 класс в волгограде [url=http://arus-diplom23.ru]купить аттестат за 11 класс в волгограде[/url] .
Diplomi_kuol
1 Aug 25 at 4:45 pm
Wow, wonderful weblog format! How lengthy have you been blogging for? you make running a blog look easy. The whole look of your web site is great, let alone the content!
where can i get generic vermox
LhaneDrync
1 Aug 25 at 4:47 pm
Среди преимуществ услуги:
Ознакомиться с деталями – [url=https://narkolog-na-dom-chelyabinsk13.ru/]вызвать нарколога на дом срочно челябинск[/url]
WilliamBug
1 Aug 25 at 4:50 pm
смотреть хорошее кино новые сериалы 2025
zfilm-82
1 Aug 25 at 4:53 pm
Психотерапевтические программы включают индивидуальные и групповые занятия, направленные на восстановление психологического состояния и формирование мотивации к трезвому образу жизни. Важной частью терапии является работа с родственниками пациента, что способствует укреплению социальной поддержки. Информацию о современных методах психотерапии можно найти на сайте Российской психотерапевтической ассоциации.
Подробнее тут – [url=https://narkologicheskaya-klinika-chelyabinsk13.ru/]наркологическая клиника клиника помощь[/url]
JudsonDualf
1 Aug 25 at 4:53 pm
фильмы онлайн hd онлайн кинотеатр
zfilm-576
1 Aug 25 at 4:53 pm
Ищете рейтинг лучших сервисов виртуальных номеров? Посетите страницу https://blog.virtualnyy-nomer.ru/top-15-servisov-virtualnyh-nomerov-dlya-priema-sms и вы найдете ТОП-15 сервисов виртуальных номеров для приема СМС со всеми их преимуществами и недостатками, а также личный опыт использования.
KavowThine
1 Aug 25 at 4:54 pm
Mega сайт
RichardPep
1 Aug 25 at 4:55 pm
Домашний вывод из запоя подходит тем, кто сохраняет относительно стабильные жизненные показатели и нуждается в минимальном мониторинге. Врач приезжает в удобное для вас время, проводит все необходимые манипуляции в привычной обстановке и остаётся на связи после процедуры для оперативной консультации.
Получить дополнительную информацию – [url=https://vyvod-iz-zapoya-reutov4.ru/]вывод из запоя на дому реутов[/url]
Billyfar
1 Aug 25 at 5:00 pm
Great post, I found it very useful. Bookmarking this. Appreciate the effort.
Joie Orzech
1 Aug 25 at 5:02 pm
Нарколог на дом в Волгограде — это специализированная медицинская услуга, направленная на оказание квалифицированной помощи пациентам с зависимостями в привычной домашней обстановке. Такая форма лечения позволяет снизить стресс, связанный с госпитализацией, и обеспечивает более комфортное проведение медицинских процедур. Вызов нарколога на дом пользуется высокой востребованностью как среди пациентов с алкоголизмом, так и среди людей, страдающих от наркотической зависимости, а также при острых состояниях, требующих неотложного вмешательства.
Получить больше информации – [url=https://narkolog-na-dom-volgograd13.ru/]нарколог на дом клиника в волгограде[/url]
JeffreyEnaro
1 Aug 25 at 5:03 pm
фильм серия смотреть онлайн онлайн мультфильмы для детей
zfilm-370
1 Aug 25 at 5:04 pm
I am in fact glad to glance at this weblog posts
which includes plenty of valuable facts, thanks for providing these data.
Мелбет промокод для спортивных ставок
1 Aug 25 at 5:07 pm
Второй этап — купирование абстинентного синдрома. Под контролем нарколога вводятся современные инфузионные растворы, витамины, седативные и поддерживающие препараты. Это позволяет вывести токсины, нормализовать работу сердца, печени и почек, снять тревогу, восстановить сон. При необходимости, особенно в случаях тяжёлых запоев, может быть подключена аппаратная детоксикация (плазмаферез, гемосорбция), что помогает быстро облегчить состояние даже при длительных и тяжёлых формах зависимости.
Подробнее – https://lechenie-alkogolizma-vidnoe4.ru/lechenie-alkogolizma-stoimost-v-vidnom/
JeffreyMig
1 Aug 25 at 5:09 pm
смотреть кино в качестве смотреть фильмы онлайн
zfilm-455
1 Aug 25 at 5:09 pm
за сколько можно купить аттестат за 11 классов [url=https://arus-diplom23.ru]за сколько можно купить аттестат за 11 классов[/url] .
Diplomi_wqol
1 Aug 25 at 5:09 pm
Thanks for a marvelous posting! I truly enjoyed reading it,
you are a great author. I will ensure that I bookmark your blog and definitely will
come back down the road. I want to encourage you to definitely continue
your great job, have a nice holiday weekend!
canadian pharmacies online
1 Aug 25 at 5:11 pm
Quality posts is the key to be a focus for the visitors to pay a quick visit the web site, that’s what this site is providing.
kikototo togel
1 Aug 25 at 5:16 pm
Hello, just wanted to mention, I liked this blog post.
It was helpful. Keep on posting!
تعمیر موتور لیفان
1 Aug 25 at 5:19 pm
Clinical pearls, precautions, and practical dosing.
pdrugguide
Woodrowkes
1 Aug 25 at 5:35 pm
candycasino [url=https://www.candy-casino-2.com]https://www.candy-casino-2.com[/url] .
candy casino_rdoi
1 Aug 25 at 5:37 pm
From HbA1c to eAG and back—quick and simple. ngsp to ifcc converter
Dwightvob
1 Aug 25 at 5:40 pm
купить аттестат за 11 класс недорого [url=https://www.arus-diplom23.ru]купить аттестат за 11 класс недорого[/url] .
Diplomi_ngol
1 Aug 25 at 5:42 pm
cheapest online pharmacy india: indianpharmacy com – IndiGenix Pharmacy
Richardquaxy
1 Aug 25 at 5:45 pm
Основной этап, направленный на очищение организма от продуктов распада алкоголя и нормализацию функций внутренних органов. Применяются современные препараты с антиоксидантным и гепатопротекторным эффектом.
Ознакомиться с деталями – http://lechenie-alkogolizma-krasnodar0.ru/klinika-lecheniya-alkogolizma-krasnodar/
Fideltam
1 Aug 25 at 5:48 pm
Everyone loves what you guys are up too. This kind of clever work
and coverage! Keep up the great works guys I’ve included you guys to
blogroll.
رشته بینایی سنجی بدون کنکور
1 Aug 25 at 5:52 pm
фильмы онлайн бесплатно новинки кино 2025
zfilm-36
1 Aug 25 at 5:52 pm
диплом занесен в реестр купить [url=http://arus-diplom35.ru]диплом занесен в реестр купить[/url] .
Diplomi_wvOn
1 Aug 25 at 5:54 pm
После обращения оператор клиники уточняет все детали — состояние пациента, стаж запоев, наличие хронических болезней, принимаемые лекарства, аллергии. Далее в течение 30–60 минут на дом выезжает мобильная бригада: врач-нарколог и медсестра со всем необходимым оборудованием и медикаментами.
Подробнее – [url=https://vyvod-iz-zapoya-orekhovo-zuevo4.ru/]вывод из запоя круглосуточно[/url]
Richardbor
1 Aug 25 at 5:55 pm
Медикаментозная детоксикация позволяет быстро и безопасно очистить организм от токсинов и продуктов распада алкоголя или наркотиков, минимизируя риски осложнений. Используются препараты, которые восстанавливают работу печени, почек и других органов, а также нормализуют электролитный баланс.
Изучить вопрос глубже – [url=https://narkologicheskaya-klinika-mariupol13.ru/]наркологическая клиника стационар в мариуполе[/url]
Michaelfax
1 Aug 25 at 5:58 pm
Wow, this article is fastidious, my sister is analyzing
such things, thus I am going to let know her.
Berry
1 Aug 25 at 5:59 pm
where can i buy cheap zithromax without prescription
where buy generic zithromax
1 Aug 25 at 6:11 pm
элконтсервис
элконтсервис
1 Aug 25 at 6:12 pm
купить проведенный диплом в красноярске [url=www.arus-diplom35.ru]www.arus-diplom35.ru[/url] .
Diplomi_eqOn
1 Aug 25 at 6:15 pm
Запой — это длительный приступ непрерывного употребления алкоголя, когда человек теряет контроль над количеством выпиваемого, что приводит к серьёзному отравлению организма. Нарушение водно-солевого баланса, угнетение центральной нервной системы и риск сердечно-сосудистых осложнений требуют немедленного вмешательства. В Челябинске клиника «ЧелябМед» предлагает круглосуточную неотложную помощь на дому и в условиях стационара, гарантируя полную анонимность и комфорт пациенту.
Ознакомиться с деталями – [url=https://vivod-iz-zapoya-chelyabinsk13.ru/]наркологический вывод из запоя челябинск[/url]
Charlesjek
1 Aug 25 at 6:19 pm
Hi, all the time i used to check website posts here in the early hours in the daylight,
as i enjoy to learn more and more.
slot demo mahjong
1 Aug 25 at 6:22 pm
I just like the valuable info you provide for your articles.
I will bookmark your weblog and take a look at once more right here frequently.
I am relatively certain I’ll be informed many new stuff proper right here!
Good luck for the following!
u31 เข้าสู่ระบบ ล่าสุด
1 Aug 25 at 6:23 pm
Howdy! I realize this is kind of off-topic but I had to ask. Does running a well-established blog such as yours require a lot of work? I am brand new to running a blog but I do write in my journal every day. I’d like to start a blog so I can share my own experience and views online. Please let me know if you have any ideas or tips for new aspiring blog owners. Appreciate it!
how can i get vermox without prescription
IsmaelNek
1 Aug 25 at 6:25 pm
Свежие скидки https://1001kupon.ru выгодные акции и рабочие промокоды — всё для того, чтобы тратить меньше. Экономьте на онлайн-покупках с проверенными кодами.
1001kupon-34
1 Aug 25 at 6:26 pm
melbet bonus [url=http://melbet1038.ru]http://melbet1038.ru[/url]
melbet_whKl
1 Aug 25 at 6:31 pm
В «ВолгаМед» работают врачи-наркологи, психотерапевты и реабилитологи с опытом от 5 до 20 лет. Каждый специалист регулярно проходит повышение квалификации, участвует в научных конференциях и владеет современными методами диагностики и лечения зависимостей.
Ознакомиться с деталями – [url=https://narkologicheskaya-klinika-volgograd13.ru/]платная наркологическая клиника[/url]
Donaldwroft
1 Aug 25 at 6:39 pm
«Академия учителя» https://edu-academiauh.ru онлайн-портал для педагогов всех уровней. Методические разработки, сценарии уроков, цифровые ресурсы и курсы. Поддержка в обучении, аттестации и ежедневной работе в школе.
edu-academiauh-814
1 Aug 25 at 6:39 pm
Наркологическая клиника «ЧелябДоктор» специализируется на экстренной и плановой детоксикации пациентов с алкогольной зависимостью. Наши главные преимущества:
Изучить вопрос глубже – [url=https://kapelnica-ot-zapoya-chelyabinsk13.ru/]капельница от запоя челябинск[/url]
HerbertApefs
1 Aug 25 at 6:45 pm
Magnificent bеat ! I wish to aрprentice whilst you amend your site, how coulԀ i subscribe
for a weblog site? The account helped me a appropriate deal.
I werе a ⅼittle bit acquainted of this your broadcast offered brigһt clear idea
My websitе … Flag of Dubai uae
Flag of Dubai uae
1 Aug 25 at 6:46 pm
Наркологическая клиника в Екатеринбурге занимается широким спектром услуг, включающих как экстренную помощь, так и длительную реабилитацию пациентов с зависимостью. Ключевыми направлениями являются:
Ознакомиться с деталями – [url=https://narcologicheskaya-klinika-ekaterinburg00.ru/]наркологические клиники алкоголизм екатеринбург.[/url]
JorgeSam
1 Aug 25 at 6:46 pm
https://indigenixpharm.com/# cheapest online pharmacy india
Jessegap
1 Aug 25 at 6:47 pm
https://t.me/wine_it
Robertgum
1 Aug 25 at 6:47 pm
Завод К-ЖБИ высокоточным оборудованием располагает, и по приемлемым ценам предлагает большой ассортимент железобетонных изделий. Вся продукция имеет сертификаты. Наши мощности производственные позволяют заказы любых объемов быстро осуществлять. https://www.royalpryanik.ru/ – тут есть возможность оставить заявку уже сейчас. На ресурсе реализованные проекты представлены. Мы гарантируем внимательный подход к требованиям заказчика. Комфортные условия оплаты обеспечиваем. Выполняем оперативную доставку продукции. Открыты к сотрудничеству!
mowihNon
1 Aug 25 at 6:48 pm
Up?front contraindications to guide safe prescribing.
pocketdrugguide.com
Woodrowkes
1 Aug 25 at 6:48 pm