Tóm Tắt
1. Event là gì ?
Event
là sự kiện, là một hành đông hay một tác vụ nào đó xả ra ở một thời điểm xác định. Trong những hệ thống web của chúng ta cũng có rất nhiều sự kiện xảy ra. Ví dụ như sự kiện một sản phẩm mới vừa được tạo, hay sự kiện khi chúng ta nhấn vào một button nào đỏ, hay đổi khi trên Facebook chúng ta cũng có những nut like, dislike cũng là một sự kiện…vv. Đôi khi chúng ta cần xử lý những sự kiện này hay nói một cách khác đó chính là cần một phản hồi lại cho user khi kích hoạt một sự kiện nào đó trong hệ thống của chúng ta. Để làm được điều này thì thật may mắn Laravel cũng cấp cho chúng ta cái gọi là Event
. Để dễ hiểu hơn một chút thì trong bài viết này mình sẽ đưa ra một ví dụ thực tế cụ thể đó chính là khi một chương trình quảng cáo được tạo ra thì chúng ta se gửi mail cho người dùng hệ thống.
2. Ví dụ cụ thể
2.1 Đặt vấn đề
Bài toán của tất cả chúng ta đưa ra là gửi mail cho tổng thể người dùng mạng lưới hệ thống khi có một chương trình quảng cáo được tạo ra .
Thực thi bài toán
Giả sử bảng discounts của tất cả chúng ta chỉ có những trường sau : id, title, content, created_at, updated_at cho nó đơn thuần nhé. Sau đó những bạn tạo Mã Sản Phẩm, migration
Tạo Event và Listener
Tiếp theo chúng ta sẽ tạo event và listener nhé, folder chứa sự kiện là app\Events
, folder chứa listener là app\Listeners
. Nhưng ban đầu khi init project Laravel thì các bạn sẽ không thấy đâu, chúng ta có thể tự tạo hoặc sử dụng hỗ trợ command line Artisan. Chúng ta có 2 cách để tạo sự kiện và listener bằng command line
Bạn đang đọc: Tìm hiểu Event trong Laravel – Blog Văn Long
php artisan make:event DiscountEvent
// và chúng ta tạo listerner tương ứng cho sự kiện này
php artisan make:listener SendEmailDiscountEvent –event=”DiscountEvent”
//sau khi tạo ra event là listener ở trên chúng ta phải vào app/Providers/EventServiceProvider.php để khai báo
12345 |
protectedUSDlisten=[ ‘ App \ Events \ DiscountEvent ‘=>[ ‘ App \ Listeners \ SendEmailDiscountEvent ‘ ], ]; |
hoặc là chúng ta sẽ khai báo trước trong app/Providers/EventServiceProvider.php
như trên và sau đó sử dụng câu lệnh sau để generate ra event và listener
php artisan event : generate
Mình thì hay dùng cách thứ 2 hơn vì nó nhanh gọn
Cách định nghĩa Event và Listener
12345678910111213141516171819202122232425 |
namespaceApp\Events; useIlluminate\Broadcasting\Channel; useIlluminate\Queue\SerializesModels; useIlluminate\Broadcasting\PrivateChannel; useIlluminate\Broadcasting\PresenceChannel; useIlluminate\Foundation\Events\Dispatchable; useIlluminate\Broadcasting\InteractsWithSockets; useIlluminate\Contracts\Broadcasting\ShouldBroadcast; useApp\Discount; classSendEmailUser { useDispatchable,InteractsWithSockets,SerializesModels; publicUSDdiscount; / * * * Create a new event instance . * * @ return void * / publicfunction__construct(DiscountUSDdiscount) { USDthis->discount=USDdiscount; } } |
Như chúng ta thấy event này của chúng ta không chứa bất cứ logic nào. Nó đơn giản là một container cho đối tượng Discount
.
Tiếp theo khi sự kiện đã được kích hoạt thì chúng ta cần một phản hồi lại cho sự kiện, lúc đó Listener
sẽ đảm nhận nhiệm vu này
12345678910111213141516171819202122232425262728 |
namespaceApp\Listeners; useApp\Events\DiscountEvent; useIlluminate\Queue\InteractsWithQueue; useIlluminate\Contracts\Queue\ShouldQueue; classListenerSendEmailEvent { / * * * Create the event listener . * * @ return void * / publicfunction__construct() { / / } / * * * Handle the event . * * @ param Discount $ event * @ return void * / publicfunctionhandle(DiscountEventUSDevent) { / / } |
Phương thức handle()
với tham số đầu vào là một instance của Event mà Listener được gán vào. Phương thức này sẽ được dùng để thực hiện các công việc cần thiết để phản hồi hay đáp lại Event mà nó theo dõi. Instance đầu vào của phương thức này cũng chứa cá các giá trị mà Event truyền sang. Ví dụ ta sẽ xử lý sự kiện mà mình đã nếu trong bài toán của chúng ta như sau:
12345678 |
public function handle(DiscountEventUSDevent) { USDusers=User::all(); foreach(USDusersasUSDuser){ Mail::to(USDuser->email) ->send(newSendEmailUser(USDevent->discount)); } } |
Trong phương thức hanlde()
trên nếu bạn muốn ngừng cái hồi đáp từ listener cho event thì bạn có thể return false
để dừng ngay những phản hồi đó. 1 vấn đề ở đây là nếu gửi mail cho tất cả các thành viên khi ấn submit bài post thì sẽ cực kỳ lâu. Các bạn có thể tìm hiểu BackgroudJob
, trong Laravel nó là Queue. Các bạn có thể xếp event listener vào hàng đợi để quá trình khi submit bài post không bị chờ đợi load quá lâu.
2.2.3. Queue
Việc gửi mail cho tất cả người dùng trong hệ thống là khá tốn thời gian. Thay vì khi submit một chương trình discount phải chờ đợi cho nó load hết để gửi hết mail cho mọi người thì chúng ta có thể gác việc gửi mail sang một bên bằng cách đưa việc gửi mail 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
12345 |
useIlluminate\Contracts\Queue\ShouldQueue; classSendMailDiscountEventimplementsShouldQueue { / / … } |
2.2.3.Kích hoạt Event.
Có rất nhiều cách để kích hoạt Event trong Laravel, các bạn tham khảo một số cách sau nhé. Cách đầu tiên chúng ta sẽ sử dụng helper event
.
1234567891011 |
publicfunctionstore(RequestUSDrequest) { USDdiscount=newDiscount(); USDdiscount->title=USDrequest->title; USDdiscount->content=USDrequest->content; USDdiscount->save();
event(newDiscountEvent(USDdiscount));
returnredirect()->route(‘ discounts ‘); } |
Cách thứ 2 chúng ta sẽ sử dụng Facade Event
1234567891011 |
publicfunctionstore(RequestUSDrequest) { USDdiscount=newDiscount(); USDdiscount->title=USDrequest->title; USDdiscount->content=USDrequest->content; USDdiscount->save();
Event::fire(‘ discount ‘,[‘ discount ‘=>USDdiscount]);
returnredirect()->route(‘ discounts ‘); } |
Xong rồi trong app / Providers / EventServiceProvider. php tất cả chúng ta cần ĐK listener nào sẽ Giao hàng sự kiện này .
123456 |
publicfunctionboot() { parent::boot(); Event::listen(‘ discount ‘,’ App \ Events \ DiscountEvent ‘); } Xem thêm: Ép kiểu trong Java | How Kteam |
Source: https://final-blade.com
Category: Kiến thức Internet