Event trong Laravel
Contents
1. Mở đầu
Event là sự kiện là một hành động hay một tác vụ nào đó xảy ra ở một thời điêm xác định.Trong đời thường cũng như trong quá trình hoạt động của một ứng dụng có rất nhiều event xảy ra. Ví dụ như trong ứng dụng web của chúng ta khi người dùng click lên một button là một sự kiện, khi người dùng thêm sản phẩm vào giỏ hàng là một sự kiện..v.v.. Đôi khi chúng ta cần xử lý các sự kiện này, và định nghĩa các tác vụ mà ứng dụng của chúng ta cần phản hồi lại khi một sự kiện xác định xảy ra. Để giúp chúng ta làm được việc này laravel cung cấp cho chúng ta cái gọi là Event. Để biết được cách sử dụng event trong laravel cụ thể ra sao. Mình xin đưa ra một trường hợp thực tế như sau đây..
2. Gửi mail xác nhận đơn hàng khi có sự kiện khách hàng Order sản phẩm
Đây là một trường hợp thực tế hay gặp nhất là khi chúng ta xây dựng ứng dụng web thương mại điện tử. Khi khách hàng đặt hàng, xem lại thông tin giỏ hàng và quyết định submit đơn hàng. Ứng dụng web của chúng ta sẽ gửi một email về thông tin chi tiết đơn hàng, tổng thanh toán và thông tin thanh toán thêm lần nữa vào email cho khách hàng xác nhận hoặc lưu trữ, đối chiếu thông tin đơn hàng khi cần thiết. Bây giờ mình xin hướng dẫn cách tạo event, lắng nghe event và gửi mail cho trường hợp đã mô tả trên đây.
2.1 Đăng ký event và listener
Laravel cung cấp cho chúng ta một cách thuận tiện để bạn có thể đăng ký event và listener cho event của bạn, bằng cách truy cập vào app\Providers\EventServiceProvider trong file này bạn đăng ký event và listener tương ứng như sau :
protected $listen = [ 'App\Events\CustomerOrder' => [ 'App\Listeners\SendMailConfirmOrder', ], ];
Trong đó:
- customerOrder Là tên sự kiện khi người dùng đặt hàng
- sendMailConfirmOrder là tên listener tương ứng với sự kiện customerOrder. Như bạn cũng có thể đoán được, ta sẽ lắng nghe sự kiện người dùng đặt hàng và khi nó xảy ra. Ta sẽ gửi một email xác nhận đơn hàng tới người dùng
2.2 Sinh class event và listener
Sau khi đăng ký như bước trên. Bạn chạy lệnh sau :
php artisan event:generate
Kiểm tra lại, có thể thấy lúc này trong project của chúng ta đã sinh thêm hai folder là Events và Listeners trong hai folder này chức hai file tương ứng là customerOrder.php và sendMailConfirmOrder.php
2.3 Định nghĩa sự kiện
Trong file customerOrder ta định nghĩa thêm thuộc tính và hàm construct như sau
<?php namespace App\Events; use Illuminate\Broadcasting\Channel; use Illuminate\Queue\SerializesModels; use Illuminate\Broadcasting\PrivateChannel; use Illuminate\Broadcasting\PresenceChannel; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Broadcasting\InteractsWithSockets; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; use App\Bills; use App\Customer; class CustomerOrder { use Dispatchable, InteractsWithSockets, SerializesModels; /** * Create a new event instance. * * @return void */ public $bill; public function __construct(Bills $userBillInfor) { $this->bill = $userBillInfor; } /** * Get the channels the event should broadcast on. * * @return Channel|array */ public function broadcastOn() { return new PrivateChannel('channel-name'); } }
Ở đây tham số truyền vào hàm construct của event là một instance của model Bill ( Để ta lấy thông tin đơn hàng mà khách hàng vừa đặt )
2.4 Định nghĩa Listener
<?php namespace App\Listeners; use App\Events\customerOrder; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Contracts\Queue\ShouldQueue; use Mail; use App\Mail\SubmitOrderMail; class SendMailConfirmOrder { /** * Create the event listener. * * @return void */ public function __construct() { // } /** * Handle the event. * * @param customerOrder $event * @return void */ public function handle(customerOrder $event) { Mail::to($event->bill->customer->email) ->send(new SubmitOrderMail($event->bill->customer, $event->bill)); } }
public function handle() là phương thức chịu trách nhiệm xử lý tác vụ đáp lại một sự kiện khi nó xảy ra. Trong trường hợp này, khi người dùng nhấn submit order thì sự kiện sẽ được kích hoạt, listener sẽ lắng nghe và bắt lấy sự kiện này và gửi mail cho khách hàng… Còn việc gửi mail chi tiết như thế nào, thì đã có khá nhiều bài viết trên Viblo bạn có thể tham khảo một sô bài viết khác trên viblo ở đây, hay ở đây …v..v Trong đoạn code trên, ta có thể truy cập đến biến bill mà ta đã khai báo khi định nghĩa event bằng cách truy cập $event->bill
, như bạn có thể thấy ở trên.
2.5 Phát đi sự kiện
Bây giờ ta cần phát đi sự kiện. Từ nãy đến giờ là cúng ta ngầm hiểu khi khách hàng submit order là sự kiển xảy ra. Nhưng máy tính thì đâu tự động hiểu được chuyện đó. Chúng ta cần phải có đoạn code để máy tính biết được lúc nào thì nên phát ra sự kiện. Giả sử trong ứng dụng của chúng ta. Khi khách hàng xem xong giỏ hàng và quyết định đặt hàng. Một form sẽ được gửi lên server và được xử lý bằng controller tên là ProcessBillController và phương thức xử lý request vừa xong trong controller này là processSubmitOrder trong phương thức này ta phát đi sự kiện bằng cách
public function processSubmitOrder(Request $request){ //...lưu thông tin vào đơn hàng..v..vv event(new customerOrder($bill)); }
- event(new customerOrder($bill)); sẽ phát đi sự kiện customerOrder. Lúc này, Listener sendMailConfirmOrder sẽ đón nhận sự kiện trên và phản hồi bằng việc gửi đi một Email xác thực đơn hàng….
- Bạn lưu ý rằng để sử dụng được customerOrder bạn cần khai báo nha use App\Events\CustomerOrder;
2.6 Xếp event listener vào hàng đợi
Việc này có thể hiểu là sau khi khách hàng nhấn đặt hàng. Thay vì để khách hàng đợi ứng dụng gửi mail xong mới phản hồi (Ứng dụng sẽ bị chậm) thì ta tạm thời gác việc gửi mail sang một bên và báo luôn đặt hàng thành công cho khách hàng. Còn việc gửi mail sẽ đưa vào hàng đợi và gửi dần sau đó… Để áp dụng Queue cho listener ta chỉ cần implement interface ShouldQueue
vào listener như dưới đây
use Illuminate\Contracts\Queue\ShouldQueue; class SendMailConfirmOrder implements ShouldQueue { //... }
Khi đó, khi Listener được gọi bởi một Event, nó sẽ tự động được đưa vào hàng đợi bởi hệ thống hàng đợi của Laravel. Nếu không có exception nào xảy ra, queue job sẽ tự động được xóa sau khi nó hoàn thành xử lý.
Mình có bài hướng dẫn về queue trong laravel rồi, bạn nào chưa biết thì vào xem nhá.
Kết Luận
Đây là bài viết mình đọc được và thấy rất hay và hữu ích. Đây là link của bài viết: https://viblo.asia/p/event-trong-laravel-YWOZryYrKQ0. Bài viết sau mình sẽ hướng dẫn các bạn resource trong laravel.