O sistema de eventos do Laravel é fenomenal quando se trata de lidar com dados complexos em nossos aplicativos da web, pois é a base para a construção de aplicativos desacoplados e absolutamente complexos. Este guia conta pontos extremamente detalhados sobre implementação e utilização de escuta de eventos, especialmente em 2024, fornecendo uma nova perspectiva com o conteúdo mais expansivo e exemplos de código detalhados de ouvintes de eventos no Laravel 11.
*(A) Compreendendo o núcleo por trás dos eventos e ouvintes
*
ENTÃO, VAMOS QUEBRÁ-LOS, os eventos no Laravel representam ocorrências específicas dentro de um aplicativo. Listeners são as classes que responderiam a todos esses eventos de aplicativo. Esse padrão continua promovendo uma separação de interesses e tem permitido códigos mais modulares e testáveis.
*(B) Criando um evento
*
Vamos começar criando um evento ainda mais complexo para isso usaremos o comando Artisan para explicar melhor, sugerimos que você faça isso também
php artesão make:evento OrderPlaced
Este comando irá gerar uma nova classe de evento no diretório app/Events. Vamos examinar uma classe de evento mais detalhada
`namespace Aplicativo\Eventos;
use App\Modelos\Ordem;
use App\Modelos\Usuário;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializeModels;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
classe OrderPlaced implementa ShouldBroadcast
{
use 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'; }
}`
Neste exemplo expandido, incluímos os modelos Order e User. A característica SerializeModels tem garantido que nossos modelos Eloquent sejam serializados e desserializados corretamente quando o evento é passado para ouvintes enfileirados. Também implementamos a interface ShouldBroadcast e definimos os métodos broadcastOn e broadcastAs, permitindo que este evento seja transmitido para websockets para atualizações em tempo real.
*Criando vários ouvintes
*
Para um único evento, podemos querer vários ouvintes. Vamos criar dois ouvintes para nosso evento OrderPlaced para expandir ainda mais o exemplo. Eu só quero que vocês tenham certeza de que entenderam a essência de tudo. Então, para isso veja o exemplo de código abaixo
php artesão make:listener SendOrderConfirmation --event=OrderPlaced
php artesão make:listener UpdateInventory --event=OrderPlaced
Então agora você entenderia que esta linha de comando nos daria algumas novas classes de ouvinte no nosso diretório app/Listeners. Agora, a questão é que, aqui abaixo, examinaríamos o ouvinte SendOrderConfirmation e veríamos como ele progride
`namespace App\Listeners;
usar aplicativo\Eventos\OrderPlaced;
use App\Mail\OrderConfirmation;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Mail;
use Iluminar\Suporte\Facades\Log;
classe SendOrderConfirmation implementa ShouldQueue
{
usar 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()]); }
}`
Este ouvinte está implementando a interface ShouldQueue, indicando que ela deve ser colocada na fila. Adicionamos tratamento de erros, registro e definimos um método com falha para lidar com falhas. A propriedade $tries seria definida para permitir múltiplas tentativas em caso de falha.
Agora, vamos dar uma olhada no ouvinte UpdateInventory
`namespace App\Listeners;
usar aplicativo\Eventos\OrderPlaced;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\DB;
use Iluminar\Suporte\Facades\Log;
classe UpdateInventory implementa ShouldQueue
{
usar 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 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()]); }
}`
Agora, você entenderia que esse ouvinte está lá por motivos como atualizar o inventário com base nos itens do pedido, etc. Envolvemos a atualização do inventário em uma transação de banco de dados para garantir a consistência dos dados. Também adicionamos verificação de erros para evitar estoque negativo e incluímos o registro de atualizações e falhas bem-sucedidas.
*Registrando eventos e ouvintes
*
Estaremos registrando esses eventos e ouvintes no EventServiceProvider
`use Aplicativo\Eventos\OrderPlaced;
use App\Listeners\SendOrderConfirmation;
use App\Listeners\UpdateInventory;
classe EventServiceProvider estende ServiceProvider
{
/**
* Os mapeamentos do ouvinte de eventos para o aplicativo.
*
* @var matriz
*/
protegido $ ouvir = [
Pedido feito::class => [
SendOrderConfirmation::class,
AtualizarInventário::classe,
],
];
/** * Register any events for your application. * * @return void */ public function boot() { parent::boot(); // }
}`
Eventos de envio:
Podemos despachar o evento de um controlador ou classe de serviço
`use Aplicativo\Eventos\OrderPlaced;
use App\Modelos\Ordem;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class OrderController estende Controlador
{
/**
* Faça um novo pedido.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
*/
função pública placeOrder(Solicitação $solicitação)
{
$usuário = auth()->usuário();
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]); }
}`
Neste exemplo, agrupamos a criação do pedido e o envio do evento em uma transação de banco de dados para garantir que ambos ocorram com sucesso ou não ocorram.
Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.
Copyright© 2022 湘ICP备2022001581号-3