An event is a way for a class to provide notifications to clients of that class when some action is occurred in an object to which the client classes may have interest. It provides a useful way for objects to signal state changes to clients of that object. When the event occurs, the handlers functions subscribed to it by its clients are invoked.
You can attach custom code to an event so that when the event is triggered, the code in the handler function gets executed. For example, a mailer object may trigger a messageSent event when it successfully sends a message. If you want to keep track of the messages that are successfully sent, you could then simply attach the tracking code to the messageSent event.
Yii2 provides a base class called yii\base\Component
to support events. If you want a custom class needs to trigger events, you have to
extend from yii\base\Component
base class, or from a its child class.
Referenced from: http://www.yiiframework.com/doc-2.0/guide-concept-events.html
In this post I will demonstrate the events mechanism by developing an example.
Lets create a scenario, we have two classes Customer
and Order
, and both these classes we need to trigger an event on registration. We add methods RegisterCustomer
and RegisterOrder
to these classes, and will trigger events EVENT_CUSTOMER_REGISTERED
and EVENT_ORDER_REGISTERED
respectively.
For demonstration purpose I will put a message in a session variable on each event, and for this we need to create a global function that will act as the single handler to events.
Then we use a separate view for displaying message reading from the session variable to verify if our event is successfully triggered and the handler function has actually placed an event message in session variable.
I have download the basic project template for http://www.yiiframework.com/download/, and start adding our code to this project already have all things setup to start.
First create a Customer class by extending from yii\base\Component
base class. Here is the code listing for Customer.php
:
<?php namespace app\components; use yii\base\Component; use yii\base\Event; class Customer extends Component { const EVENT_CUSTOMER_REGISTERED = 'CUSTOMER_REGISTERED'; public function RegisterCustomer() { $this->trigger(self::EVENT_CUSTOMER_REGISTERED); } }
You might noticed that the basic project tempalte folder you downloaded, do not have the components
folder by-default, you can simply create this folder in the root directory and save Customer.php
file in this folder.
Similary we can create Order.php
as follows:
<?php namespace app\components; use yii\base\Component; use yii\base\Event; class Order extends Component { const EVENT_ORDER_REGISTERED = 'ORDER_REGISTERED'; public function RegisterOrder() { $this->trigger(self::EVENT_ORDER_REGISTERED); } }
I created a TestController
with Index view as the home page for this demo, providing two buttons to register customer and order.
Register Customer
button will call the actionRegisterCustomer
action in TestController
. Inside this action method, we create a Customer object, attach our global event handler
function on this $customer
object by using on
function for attaching events. And finally for just demonstrating purpose I manually call RegisterCustomer
function on $customer object which will trigger the event EVENT_CUSTOMER_REGISTERED
. Then we simply return the render function call
with view-message
to display a message stored in session variable by global event handler function.
public function actionRegisterCustomer() { //create customer component object $customer = new Customer; //first clear session, so our event will set message in this session variable setSession('eventMessage', null); //attach event handler, 'genericEventHandlerFunction' is the name of global function with accepting one argument $event $customer->on(Customer::EVENT_CUSTOMER_REGISTERED, 'genericEventHandlerFunction','Customer register event data'); //this function will trigger event $customer->RegisterCustomer(); //this view will display message generated by event return $this->render('view-message'); }
Similarly the Register Order
button will call the actionRegisterOrder
action in TestController
, and follows the same procedure for function call, attach event handler,
event trigger function call, and finally return the same view-message
;
public function actionRegisterOrder() { //create order component object $order = new Order; //first clear session, so our event will set message in this session variable setSession('eventMessage', null); //attach event handler, 'genericEventHandlerFunction' is the name of global function with accepting one argument $event $order->on(Order::EVENT_ORDER_REGISTERED, 'genericEventHandlerFunction','Order register event data'); //this function will trigger event $order->RegisterOrder(); //this view will display message generated by event return $this->render('view-message'); }
Now add a generic handler function which will store string message in session. Place this function in config\Globals.php file (if this file not already exists, you can create it to place all global functions or variables in one place).
function genericEventHandlerFunction($event) { $msg = 'Event handled with data: ' . $event->data; Yii::$app->session->set('eventMessage', $msg); }
Finally let come to the view part, in our view-message.php, we extract the message from session and display it in the html.
<div class="alert alert-success" > <?php echo getSession('eventMessage'); ?> </div>
It will display the following message when you clicked Register Customer
button:
And you will get order registration message on Register Order
button click:
References:
http://www.yiiframework.com/doc-2.0/guide-concept-events.html
Hello,
ReplyDeleteThanks for awesome start guide.
I have one question here is the where is the code of "genericEventHandlerFunction" ? where we have to create or define it ?
Thanks Kalpesh, Yes it was missed. I appreciate your time for reading this article and pointing the mistake to improve. I have fixed it and updated the article.
DeleteThanks Muhammad Idrees, I have created global function using following link : https://yii2-cookbook.readthedocs.io/structure-global-functions/
DeleteYes, that's nice idea.
DeleteReally awesome blog. Your blog is really useful for me. Thanks for sharing this informative blog. Keep update your blog.
ReplyDeleteDedicated Yii Framework Developers