Service decoupling through events and event listeners
brief introduction
Register event/listener
/** *Applied event listener mapping * * @var array * @translator laravelacademy.org */ protected $listen = [ 'App\Events\OrderShipped' => [ 'App\Listeners\SendShipmentNotification', ], ];
Generate event/listener class
php artisan event:generate
Manually register events
/** *Register other events of the application * * @return void */ public function boot() { parent::boot(); Event::listen('event.name', function ($foo, $bar) { // }); }
$events->listen('event.*', function ($eventName, array $data) { // });
Define Events
<? php namespace App\Events; use App\Order; use Illuminate\Queue\SerializesModels; class OrderShipped { use SerializesModels; public $order; /** *Create a new event instance * * @param Order $order * @return void */ public function __construct(Order $order) { $this->order = $order; } }
Define Listener
<? php namespace App\Listeners; use App\Events\OrderShipped; class SendShipmentNotification { /** *Create an event listener * * @return void */ public function __construct() { // } /** *Handling events * * @param OrderShipped $event * @return void */ public function handle(OrderShipped $event) { //Use $event ->order to send and access orders } }
Note: The event listener can also prompt any required dependency in the constructor. All event listeners are resolved through the service container, so the dependency will be automatically injected.
Event listener queue
<? php namespace App\Listeners; use App\Events\OrderShipped; use Illuminate\Contracts\Queue\ShouldQueue; class SendShipmentNotification implements ShouldQueue { // }
<? php namespace App\Listeners; use App\Events\OrderShipped; use Illuminate\Contracts\Queue\ShouldQueue; class SendShipmentNotification implements ShouldQueue { /** *The name of the connection to which the task will be pushed * * @var string|null */ public $connection = 'sqs'; /** *The name of the connection to which the task will be pushed * * @var string|null */ public $queue = 'listeners'; }
Manual access to queues
<? php namespace App\Listeners; use App\Events\OrderShipped; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Contracts\Queue\ShouldQueue; class SendShipmentNotification implements ShouldQueue { use InteractsWithQueue; public function handle(OrderShipped $event) { if (true) { $this->release(30); } } }
Processing failed tasks
<? php namespace App\Listeners; use App\Events\OrderShipped; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Contracts\Queue\ShouldQueue; class SendShipmentNotification implements ShouldQueue { use InteractsWithQueue; public function handle(OrderShipped $event) { // } public function failed(OrderShipped $event, $exception) { // } }
Distribute Events
<? php namespace App\Http\Controllers; use App\Order; use App\Events\OrderShipped; use App\Http\Controllers\Controller; class OrderController extends Controller { /** *Process the given order * * @param int $orderId * @return Response */ public function ship($orderId) { $order = Order::findOrFail($orderId); //Order Processing Logic event(new OrderShipped($order)); } }
Note: When testing, it is only necessary to assert that specific events are distributed without actually triggering the listener, Laravel Built in test function Make this easy.
Event Subscriber
Write event subscriber
<? php namespace App\Listeners; class UserEventSubscriber { /** *Handle user login events * @translator laravelacademy.org */ public function onUserLogin($event) {} /** *Handle the user exit event */ public function onUserLogout($event) {} /** *Register listeners for subscribers * * @param Illuminate\Events\Dispatcher $events */ public function subscribe($events) { $events->listen( 'Illuminate\Auth\Events\Login', 'App\Listeners\ UserEventSubscriber@onUserLogin ' ); $events->listen( 'Illuminate\Auth\Events\Logout', 'App\Listeners\ UserEventSubscriber@onUserLogout ' ); } }
Register event subscribers
<? php namespace App\Providers; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; class EventServiceProvider extends ServiceProvider { /** *Applied event listener mapping * * @var array */ protected $listen = [ // ]; /** *Subscriber class to register * * @var array */ protected $subscribe = [ 'App\Listeners\UserEventSubscriber', ]; }