Laravel でイベント リスナーを使用する方法とタイミング 実践的なコード例

王林
リリース: 2024-08-16 07:03:02
オリジナル
288 人が閲覧しました

How & When To Use Event Listeners in Laravel  Practical Code Examples

Laravel のイベント システムは、分離された完全に複雑なアプリを構築するための基礎となるため、Web アプリ内の複雑なデータを処理することに関しては驚異的です。このガイドでは、特に 2024 年におけるイベント リスニングの実装と利用に関する非常に詳細なポイントについて説明し、Laravel 11 のイベント リスナーの最も広範な内容と詳細なコード サンプルによる新たな視点を提供します。

*(A) イベントとリスナーの背後にあるコアを理解する
*

それでは、詳しく見てみましょう。Laravel のイベントは、アプリ内での特定の出来事を表します。リスナーは、そのようなすべてのアプリ イベントに応答するクラスです。このパターンは懸念事項の分離を促進し続け、よりモジュール化されたテスト可能なコードを可能にします。

*(B) イベントの作成
*

まず、複雑なイベントを作成することから始めましょう。このイベントについては、アーティザン コマンドを使用して説明します。これを行うことを強くお勧めします

phpArtisan make:event OrderPlaced

このコマンドは、app/Events ディレクトリに新しいイベント クラスを生成します。より詳細なイベント クラスを調べてみましょう

`名前空間 AppEvents;

AppModelsOrder を使用します;
AppModelsUser を使用します;
IlluminateFoundationEventsDispatchable を使用します;
IlluminateQueueSerializesModels を使用します;
IlluminateBroadcastingInteractsWithSockets を使用します;
IlluminateBroadcastingPrivateChannel を使用します;
IlluminateContractsBroadcastingShouldBroadcast を使用します;

クラス OrderPlaced は ShouldBroadcast を実装します
{
Dispatchable、InteractsWithSockets、SerializesModels を使用します;

public $order;
public $user;

/**
 * Create a new event instance.
 *
 * @param  \App\Models\Order  $order
 * @param  \App\Models\User  $user
 * @return void
 */
public function __construct(Order $order, User $user)
{
    $this->order = $order;
    $this->user = $user;
}

/**
 * Get the channels the event should broadcast on.
 *
 * @return \Illuminate\Broadcasting\Channel|array
 */
public function broadcastOn()
{
    return new PrivateChannel('orders.'.$this->user->id);
}

/**
 * The event's broadcast name.
 *
 * @return string
 */
public function broadcastAs()
{
    return 'order.placed';
}
ログイン後にコピー

}`

この拡張された例では、Order モデルと User モデルの両方が含まれています。 SerializesModels トレイトは、イベントがキューに入れられたリスナーに渡されるときに、Eloquent モデルが正しくシリアル化および逆シリアル化されることを保証します。また、ShouldBroadcast インターフェースを実装し、broadcastOn メソッドと broadcastAs メソッドを定義して、このイベントを WebSocket にブロードキャストしてリアルタイム更新できるようにしました。

*複数のリスナーの作成
*

1 つのイベントに対して、複数のリスナーが必要になる場合があります。例をさらに拡張するために、OrderPlaced イベント用の 2 つのリスナーを作成してみましょう。皆さんには、すべての要点を確実に理解していただきたいと思います。そのため、以下のコード例を参照してください

php職人make:listener SendOrderconfirmation --event=OrderPlaced
php 職人 make:listener UpdateInventory --event=OrderPlaced

このコマンドラインにより、app/Listeners ディレクトリにいくつかの新しいリスナー クラスが取得されることがわかりました。ここで重要なのは、以下で SendOrderconfirmation リスナーを調べて、それがさらにどのように進行するかを確認することです

`名前空間 AppListeners;

AppEventsOrderPlaced を使用します;
AppMailOrderconfirmation を使用します;
IlluminateContractsQueueShouldQueue を使用します;
IlluminateQueueInteractsWithQueue を使用します;
IlluminateSupportFacadesMail を使用します;
IlluminateSupportFacadesLog を使用します;

クラス SendOrderconfirmation は ShouldQueue を実装します
{
InteractsWithQueue を使用します;

/**
 * The number of times the job may be attempted.
 *
 * @var int
 */
public $tries = 3;

/**
 * Handle the event.
 *
 * @param  \App\Events\OrderPlaced  $event
 * @return void
 */
public function handle(OrderPlaced $event)
{
    $order = $event->order;
    $user = $event->user;

    try {
        Mail::to($user->email)->send(new OrderConfirmation($order));
        Log::info('Order confirmation email sent', ['order_id' => $order->id, 'user_id' => $user->id]);
    } catch (\Exception $e) {
        Log::error('Failed to send order confirmation email', ['order_id' => $order->id, 'user_id' => $user->id, 'error' => $e->getMessage()]);
        $this->fail($e);
    }
}

/**
 * Handle a job failure.
 *
 * @param  \App\Events\OrderPlaced  $event
 * @param  \Throwable  $exception
 * @return void
 */
public function failed(OrderPlaced $event, $exception)
{
    Log::error('Order confirmation listener failed', ['order_id' => $event->order->id, 'user_id' => $event->user->id, 'error' => $exception->getMessage()]);
}
ログイン後にコピー

}`

このリスナーは ShouldQueue インターフェースを実装しており、キューに入れる必要があることを示しています。エラー処理とログ記録を追加し、失敗を処理する失敗したメソッドを定義しました。 $tries プロパティは、失敗した場合に複数の試行を許可するように設定されます。
次に、UpdateInventory リスナー

を見てみましょう。

`名前空間 AppListeners;

AppEventsOrderPlaced を使用します;
IlluminateContractsQueueShouldQueue を使用します;
IlluminateQueueInteractsWithQueue を使用します;
IlluminateSupportFacadesDB を使用します;
IlluminateSupportFacadesLog を使用します;

クラス UpdateInventory は ShouldQueue を実装します
{
InteractsWithQueue を使用します;

/**
 * Handle the event.
 *
 * @param  \App\Events\OrderPlaced  $event
 * @return void
 */
public function handle(OrderPlaced $event)
{
    $order = $event->order;

    DB::transaction(function () use ($order) {
        foreach ($order->items as $item) {
            $product = $item->product;

            if ($product->stock < $item->quantity) {
                throw new \Exception("Insufficient stock for product: {$product->id}");
            }

            $product->decrement('stock', $item->quantity);
            Log::info("Inventory updated", ['product_id' => $product->id, 'quantity' => $item->quantity]);
        }
    });
}

/**
 * Handle a job failure.
 *
 * @param  \App\Events\OrderPlaced  $event
 * @param  \Throwable  $exception
 * @return void
 */
public function failed(OrderPlaced $event, $exception)
{
    Log::error('Failed to update inventory', ['order_id' => $event->order->id, 'error' => $exception->getMessage()]);
}
ログイン後にコピー

}`

おわかりいただけると思いますが、このリスナーは、注文品目に基づいて在庫をアップグレードするなどの理由で存在します。データの一貫性を確保するために、在庫の更新をデータベース トランザクションでラップしました。また、マイナス在庫を防ぐためにエラー チェックを追加し、更新の成功と失敗のログを組み込みました。

*イベントとリスナーの登録
*

これらのイベントとリスナーを EventServiceProvider

に登録します。

`AppEventsOrderPlaced を使用します;
AppListenersSendOrderconfirmation を使用します;
AppListenersUpdateInventory を使用します;

class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
OrderPlaced::class => [
SendOrderConfirmation::class,
UpdateInventory::class,
],
];

/**
 * Register any events for your application.
 *
 * @return void
 */
public function boot()
{
    parent::boot();

    //
}
ログイン後にコピー

}`

Dispatching Events:

We can dispatch the event from a controller or service class

`use App\Events\OrderPlaced;
use App\Models\Order;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class OrderController extends Controller
{
/**
* Place a new order.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function placeOrder(Request $request)
{
$user = auth()->user();

    DB::transaction(function () use ($request, $user) {
        $order = Order::create($request->all());
        $order->user()->associate($user);
        $order->save();

        event(new OrderPlaced($order, $user));
    });

    return response()->json(['message' => 'Order placed successfully', 'order_id' => $order->id]);
}
ログイン後にコピー

}`

In this example, we have wrapped the order creation and event dispatching in a database transaction to ensure that both occur successfully or not at all.

以上がLaravel でイベント リスナーを使用する方法とタイミング 実践的なコード例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート