Quản lý sự kiện trong ứng dụng với Laravel Event

LAMP Nov 02, 2020

Xin chào mọi người, đây là lần đầu tiên mình viết bài chia sẻ về những điều thú vị trong Laravel. Để tiếp tục series Laravel này , hôm nay mình sẽ cùng tìm hiểu và chia sẻ về Event trong Laravel nhé.

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 đó...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 người dùng đặt order thì mình sẽ gửi email cho người dùng hệ thống và lưu nội dung order vào file .txt :))

2. Ví dụ cụ thể

Gỉa xử khi người dùng đặt order trên hệ thống của chúng ta thì hệ thống sẽ gửi email thông báo cho người dùng và lưu thông tin vào file .txt

2.1 Tạo Event và Listener

Tiếp theo chúng ta sẽ tạo event và listener , folder chứa sự kiện là app\Events, folder chứa listener là app\Listeners.

để tạo event và listener chúng ta có hai cách

a: cách 1 xử dụng command line

php artisan make:event OrderPayment

tạo listener:

php artisan make:listener SendEmailOrderShipped

lúc này chúng ta thấy Laravel sẽ generate ra 2 forder là app\Events app\Listeners

b: cách 2

chúng ta sẽ khai báo trước trong app/Providers/EventServiceProvider.php và sau đó sử dụng câu lệnh sau để generate ra event và listener

protected $listen = [
    'App\Events\OrderPayment' => [
        'App\Listeners\SaveLogOrderToFile',
        'App\Listeners\SendEmailOrderShipped',
    ]
];

sau đó xử dụng command line

php artisan event:generate

theo mình thì các bạn nên xử dụng cách hai vì nó đơn dản và nhanh gọn hơn :))

2.2 Định nghĩa Event và Listener

<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class OrderPayment
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public $order;
    public function __construct($order)
    {
        $this->order = $order;
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        return new PrivateChannel('channel-name');
    }
}
<?php

namespace App\Listeners;

use App\Events\OrderPayment;
use App\Mail\OrderShipped;
use App\Models\Order;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Mail;

class SendEmailOrderShipped implements ShouldQueue
{
    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param  OrderPayment  $event
     * @return void
     */	
    public function handle(OrderPayment $event)
    {
        $user = User::findOrFail($event->order->user_id);
        Mail::to($user->email)
            ->send(new OrderShipped($event));
    }
}
<?php

namespace App\Listeners;

use App\Events\OrderPayment;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;

class SaveLogOrderToFile implements ShouldQueue
{
    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param  OrderPayment  $event
     * @return void
     */
    
    public function handle(OrderPayment $event)
    {
        $fileLog = now(). $event->order->id. ".txt";
        $data = "amount: ". $event->order->amount. "Order ID: ". $event->order->id;
        Storage::put("LogOrder/".$fileLog, $data);
    }

    /**
     * Handle a job failure.
     *
     * @param  \App\Events\OrderShipped  $event
     * @param  \Throwable  $exception
     * @return void
     */
    public function failed(OrderPayment $event, $exception) {
        Log::debug( $exception->getMessage());
    }
   
}

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

Đôi khi, chúng ta có thể cần phải xác định xem một event có nên được queue hay không dựa trên dữ liệu có sẵn. Để thực hiện điều này, phương thức shouldQueue có thể được thêm vào trình nghe để xác định xem người nghe có nên được queue hay không. Nếu phương thức shouldQueue trả về false, event sẽ không được thực thi:

public function shouldQueue(OrderPayment $event)
    {
        return $event->order->amount >= 30000;
    }

2.3.Kích hoạt Event.

Chúng ta sẽ sử dụng helper event hoặc Facade event

<?php

namespace App\Http\Controllers;

use App\Models\Order;
use Illuminate\Http\Request;
use App\Events\OrderPayment;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Event;
class OrderController extends Controller
{
    public function store(Request  $request) {
    
        $userId = Auth::user()->id;
        $listOrder = $this->getListOrder();
        
        $order = new Order();
        $order->user_id = $userId;
        $order->name = $listOrder['name'][rand(1,5)];
        $order->amount = $listOrder['amount'][rand(1,5)];
        $order->note = "it da it duong";
        $order->save();
        
        //use Facade event
        OrderPayment::dispatch($order);
        //use helper event 
       // event(new OrderPayment($order));
       
        return redirect('/');
    }

    private function getListOrder() {
        $listOrder = [
            'name' => [
                1 => "Café Việt Nam truyền thống",
                2 => "Trà đào",
                3 => "Trà sữa chân châu",
                4 => "Trà hoa cúc mật ong",
                5 => "Cafe nước cốt dừa",
            ],
            'amount' => [
                1 => 34000,
                2 => 40000,
                3 => 45000,
                4 => 50000,
                5 => 55000,
            ]
        ];
        return $listOrder;
    }
}

lúc này khi user submit order thì hệ thống sẽ send email tới use và lưu content vào file .txt

và kết qủa sẽ như sau :))

3. Tổng kết

Vậy qua những chia sẻ của mình ở trên về Events trong Laravel mình hi vọng giúp các bạn hiểu được Event trong Laravel nó là cái gì, và khi nào cần xử dụng nó . Mong rằng qua bài chia sẻ của mình có ích đối với các bạn. Cảm ơn các bạn đã đọc bài chia sẻ của mình.

tài liệu tham khảo https://laravel.com/docs/8.x/events#introduction

Tags

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.