-
Example Laravel Events
-
Manually Defining Events
-
Using Event Subscribers
Events are an implementation of the observer pattern, where an event (or action) takes place, and then one or more listeners respond to that event.
Laravel allow you to subscribe and listen for various events that occur in your application.
Laravel's Events can be handled by the following steps:
- Add events and listeners classes in the $listen property to EventServiceProvider class (in app/Providers/EventServiceProvider.php file).
- The $listen property contains an array of all events (keys) and their listeners (values):
protected $listen =[
'App\Events\EventName_Class'=> [
'App\Listeners\ListenerName_Class',
],
];
- Initiate the following command in Command Line Interface.
- This command will generate classes for every event and listeners that are listed in EventServiceProvider (events and listeners that already exist will be left untouched).
php artisan event:generate
- Event classes will be stored in the app/Events/ directory, while their listeners are stored in app/Listeners/.
- Last step is to dispatch the event with the event(new EventName_Class()) function, or the Event::fire(new EventName_Class()) method.
- It will dispatch the event to all of EventName_Class registered listeners. It will return an array with the response of each registered listener:
//dispatches an event and gets an array with listeners responses
$event = event(new EventClass_Name($request, $msg));
/*
$event =[
0=>'response from first listener',
1=>'response from second listener',
//...
];
*/
You must add this line in the controller where events are used (
"EventName_Class" is the name of the event class):
use App\Events\EventName_Class;
- If you dispatch the event with the
Event::fire() method, you need also to add the
use Event; line in your controller.
Example Laravel Events
Here is a simple example that will help you to understand how Laravel's events work.
1. We create a controller called
TestEventController.
Copy the following code and save it in "
app/Http/Controllers/TestEventController.php".
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Events\TestEvent;
class TestEventController extends Controller {
//responds to GET /testevent
//returns view with form
public function index(){
return view('add_name_form');
}
//responds to POST /testevent
//returns view with form, passing event-listener response
public function store(Request $request){
if($request->has(['name'])){
$name = $request->name;
$msg ='<h4>Message from controller:</h4>Form data received.';
//dispatch an event and get an array [0=>'listener-response']
$event = event(new TestEvent($request, $msg))[0];
return view('add_name_form', ['event'=>$event]);
}
else return 'Not valid request.';
}
}
2. Now, set up a
resource route for TestEventController.
Add the following code in the
routes/web.php file:
Route::resource('/testevent', 'TestEventController');
3. Copy the following code in
resources/views/add_name_form.blade.php to create the view that will display the form:
@isset($event)
<div>
{!!$event !!}
</div>
@endisset
<h4>Add Name</h4>
<form method="post" action="/testevent">
{{ csrf_field() }}
<label>Name: <input type='text' name='name'/></label><br>
<input type='submit' value='Add'/>
</form>
4. We now need to register the event class and its listener class in
EventServiceProvider.php file.
- Open the
app/Providers/EventServiceProvider.php file and register the
TestEvent and
TestListener in the
$listen property, like in this code:
protected $listen =[
'App\Events\TestEvent'=> [
'App\Listeners\TestListener',
],
];
5. To generate the registered event class and its listener class, execute the following command in Command-Line-Interface:
php artisan event:generate
- After you execute the command above, Laravel will create the
app/Events/TestEvent.php class, and the listener class in
app/Listeners/TestListener.php, with some basic code.
6. Copy the following code in the
app/Events/TestEvent.php file:
<?php
namespace App\Events;
class TestEvent {
//properties that can be used in the listener class
public $name;
public $method;
public $msg;
//Create a new event instance
//Receives the http $request and a message string in $msg
//@return void
public function __construct($request, $msg){
$this->name = $request->name;
$this->method = $request->method();
$this->msg = $msg;
}
}
7. Copy the following code in the
app/Listeners/TestListener.php file:
<?php
namespace App\Listeners;
use App\Events\TestEvent;
class TestListener {
protected $name;
//Create the event listener
//@return void
public function __construct(){
//
}
//Handle the event
//@param TestEvent $event
//@return string (but in accessor it will be received into an array [0=>'string-response'])
public function handle(TestEvent $event){
$this->name = $event->name;
return $event->msg.'<h4>Message from Event-Listener:</h4>New name: '.$this->name.'<br>Using Method: '.$event->method;
}
}
- Notice that the handle() method returns a string as response, but the event() function (in controller) will return the response from listener into an array ( [0=>'response'] ).
8. Start the php build-in server (command:
php artisan serve ), and access this URL in your browser:
//localhost:8000/testevent
- After visiting the above URL, the browser will show a page with a form, like in this image:
9. Write a Name in form field and click "Add" button to test the event.
- The browser will show a page like in this image:
Manually Defining Events
An event class is simply a data container which holds the information related to the event. You can manually create the
event class in "
app/Events/" directory, and the
listener class (with a
handle() method) in "
app/Listeners/" directory.
You may use any dependencies in event-listener. Here is an example of a listener that uses
Request service (notice the red lines):
<?php
namespace App\Listeners;
use Illuminate\Http\Request;
use App\Events\Event_Name;
class Listener_Name {
protected $name;
//automatically receive the Request instance
//@return void
public function __construct(Request $request){
$this->name = $request->name;
}
//Handle the event
//@param TestEvent $event
//@return string
public function handle(TestEvent $event){
return 'New name: '.$this->name;
}
}
Then, you just need to register the event and listener classes in the
$listen property in
EventServiceProvider.php.
- You may add as many events to the
$listen array as your application requires. Also, you may add multiple listeners to a single event.
protected $listen =[
'App\Events\EventClass_1'=> [
'App\Listeners\ListenerClass_1'
],
'App\Events\EventClass_2'=> [
'App\Listeners\ListenerClass_2',
'App\Listeners\ListenerClass_3'
],
];
Stopping the Propagation of an Event
If you use multiple listeners for an event, and you want to stop the propagation of an event to other listeners. Just apply:
return false; in the listener's
handle() method.
Using Event Subscribers
Event subscriber is a class that may subscribe to multiple events from within the class itself, allowing you to define several event handlers within a single class.
Subscribers are created in the
app/Listeners/ directory, and it should contain a
subscribe() method, which will receive an
$event instance.
In
subscribe() you may call the
listen() method on the given
$event instance to register event listeners, like in this example of an event-subscriber class:
<?php
namespace App\Listeners;
class UserEventSubscriber {
//Handle user login events
public function onUserLogin($event){ return 'login';}
//Handle user logout events
public function onUserLogout($event){ return 'logout';}
//Register the listeners for the subscriber
//@param Illuminate\Events\Dispatcher $events
public function subscribe($events){
$events->listen(
'App\Events\LoginEvent',
'App\Listeners\UserEventSubscriber@onUserLogin'
);
$events->listen(
'App\Events\LogoutEvent',
'App\Listeners\UserEventSubscriber@onUserLogout'
);
}
}
- Then, you have to create the events classes (here:
LoginEvent.php and
LogoutEvent.php) in
app/Events/ directory.
Registering Event Subscribers
After writing the subscriber, you need to register it using the
$subscribe property in
EventServiceProvider.php.
- For example, let's add the
UserEventSubscriber to the list:
<?php
namespace App\Providers;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider {
//The event listener mappings for the application
//@var array
protected $listen =[
//
];
//The subscriber classes to register.
//@var array
protected $subscribe =[
'App\Listeners\UserEventSubscriber',
];
}
- In your controller, call the
event() function with the event you want to dispatch.
event(new LoginEvent());
event(new LogoutEvent());
- Documentation:
Laravel - Events