نسخه:

مناسبت ها

معرفی

رویدادهای لاراول یک اجرای ناظر ساده را ارائه می‌دهند و به شما امکان می‌دهند مشترک شوید و به رویدادهای مختلفی که در برنامه شما رخ می‌دهند گوش دهید. کلاس‌های رویداد معمولاً در app/Events دایرکتوری ذخیره می‌شوند، در حالی که شنوندگان آن‌ها در دایرکتوری ذخیره می‌شوند app/Listeners . اگر این دایرکتوری ها را در برنامه خود نمی بینید نگران نباشید، زیرا هنگام ایجاد رویدادها و شنوندگان با استفاده از دستورات کنسول Artisan، آنها برای شما ایجاد می شوند.

رویدادها راهی عالی برای جدا کردن جنبه‌های مختلف برنامه شما هستند، زیرا یک رویداد می‌تواند چندین شنونده داشته باشد که به یکدیگر وابسته نیستند. به عنوان مثال، ممکن است بخواهید هر بار که سفارش ارسال می شود، یک اعلان Slack برای کاربر خود ارسال کنید. به جای اینکه کد پردازش سفارش خود را به کد اعلان Slack متصل کنید، می توانید OrderShipped رویدادی را مطرح کنید که شنونده می تواند آن را دریافت کرده و به اعلان Slack تبدیل کند.

ثبت رویدادها و شنوندگان

همراه EventServiceProvider با برنامه لاراول شما مکانی مناسب برای ثبت نام تمام شنوندگان رویداد برنامه شما فراهم می کند. این listen ویژگی شامل آرایه ای از همه رویدادها (کلیدها) و شنوندگان آنها (مقادیر) است. می توانید هر تعداد رویداد که برنامه شما نیاز دارد به این آرایه اضافه کنید. به عنوان مثال، بیایید یک OrderShipped رویداد اضافه کنیم:

/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
'App\Events\OrderShipped' => [
'App\Listeners\SendShipmentNotification',
],
];

ایجاد رویدادها و شنوندگان

البته ایجاد دستی فایل ها برای هر رویداد و شنونده دست و پا گیر است. در عوض، شنوندگان و رویدادها را به خود اضافه کنید EventServiceProvider و از event:generate دستور استفاده کنید. این دستور هر رویداد یا شنونده ای را که در لیست شما ذکر شده است ایجاد می کند EventServiceProvider . رویدادها و شنوندگانی که از قبل وجود داشته اند دست نخورده باقی خواهند ماند:

php artisan event:generate

ثبت دستی رویدادها

به طور معمول، رویدادها باید از طریق آرایه ثبت شوند EventServiceProvider $listen . با این حال، شما همچنین می توانید رویدادهای مبتنی بر بسته شدن را به صورت دستی در boot روش خود ثبت کنید EventServiceProvider :

/**
* Register any other events for your application.
*
* @return void
*/
public function boot()
{
parent::boot();
 
Event::listen('event.name', function ($foo, $bar) {
//
});
}

شنوندگان رویداد Wildcard

حتی ممکن است شنوندگان را با استفاده از * پارامتر به عنوان علامت عام ثبت کنید، که به شما امکان می دهد چندین رویداد را در یک شنونده مشاهده کنید. شنوندگان Wildcard نام رویداد را به عنوان اولین آرگومان خود و کل آرایه داده رویداد را به عنوان آرگومان دوم دریافت می کنند:

Event::listen('event.*', function ($eventName, array $data) {
//
});

کشف رویداد

به جای ثبت رویدادها و شنوندگان به صورت دستی در $listen آرایه EventServiceProvider ، می توانید کشف خودکار رویداد را فعال کنید. هنگامی که کشف رویداد فعال است، لاراول به طور خودکار رویدادها و شنوندگان شما را با اسکن دایرکتوری برنامه شما پیدا و ثبت می کند Listeners . بعلاوه، هر رویدادی که به صراحت تعریف شده باشد، EventServiceProvider همچنان ثبت خواهد شد.

لاراول شنوندگان رویداد را با اسکن کلاس های شنونده با استفاده از بازتاب پیدا می کند. وقتی لاراول هر متد کلاس شنونده ای را پیدا می کند که با شروع آن شروع می شود handle ، لاراول آن متدها را به عنوان شنونده رویداد برای رویدادی که به صورت تایپ در امضای متد ذکر شده است، ثبت می کند:

use App\Events\PodcastProcessed;
 
class SendPodcastProcessedNotification
{
/**
* Handle the given event.
*
* @param \App\Events\PodcastProcessed
* @return void
*/
public function handle(PodcastProcessed $event)
{
//
}
}

کشف رویداد به طور پیش‌فرض غیرفعال است، اما می‌توانید با نادیده گرفتن shouldDiscoverEvents روش برنامه خود، آن را فعال کنید EventServiceProvider :

/**
* Determine if events and listeners should be automatically discovered.
*
* @return bool
*/
public function shouldDiscoverEvents()
{
return true;
}

به طور پیش فرض، همه شنوندگان در فهرست شنوندگان برنامه شما اسکن خواهند شد. اگر می‌خواهید دایرکتوری‌های دیگری را برای اسکن تعریف کنید، می‌توانید این discoverEventsWithin روش را در خود لغو کنید EventServiceProvider :

/**
* Get the listener directories that should be used to discover events.
*
* @return array
*/
protected function discoverEventsWithin()
{
return [
$this->app->path('Listeners'),
];
}

در تولید، احتمالاً نمی‌خواهید که چارچوب تمام شنوندگان شما را در هر درخواست اسکن کند. بنابراین، در طول فرآیند استقرار خود، باید event:cache دستور Artisan را اجرا کنید تا مانیفست تمام رویدادها و شنوندگان برنامه خود را در حافظه پنهان ذخیره کنید. این مانیفست توسط چارچوب برای سرعت بخشیدن به روند ثبت رویداد استفاده می شود. این event:clear دستور ممکن است برای از بین بردن حافظه پنهان استفاده شود.

این event:list دستور ممکن است برای نمایش لیستی از تمام رویدادها و شنوندگان ثبت شده توسط برنامه شما استفاده شود.

تعریف رویدادها

کلاس رویداد یک محفظه داده است که اطلاعات مربوط به رویداد را در خود نگه می دارد. به عنوان مثال، فرض کنید OrderShipped رویداد تولید شده ما یک شی ORM Eloquent دریافت می کند:

<?php
 
namespace App\Events;
 
use App\Order;
use Illuminate\Queue\SerializesModels;
 
class OrderShipped
{
use SerializesModels;
 
public $order;
 
/**
* Create a new event instance.
*
* @param \App\Order $order
* @return void
*/
public function __construct(Order $order)
{
$this->order = $order;
}
}

همانطور که می بینید، این کلاس رویداد هیچ منطقی ندارد. این یک ظرف برای Order نمونه ای است که خریداری شده است. اگر شی SerializesModels رویداد با استفاده از تابع PHP سریال‌سازی شود، ویژگی مورد استفاده رویداد، هر مدل Eloquent را به‌خوبی سریال‌سازی می‌کند serialize .

تعریف شنوندگان

در مرحله بعد، بیایید نگاهی به شنونده رویداد نمونه خود بیاندازیم. شنوندگان رویداد نمونه رویداد را در handle روش خود دریافت می کنند. دستور event:generate به طور خودکار کلاس رویداد مناسب را وارد می کند و رویداد را در handle متد تایپ می کند. در handle روش، می‌توانید هر اقدامی را که برای پاسخ دادن به رویداد لازم است انجام دهید:

<?php
 
namespace App\Listeners;
 
use App\Events\OrderShipped;
 
class SendShipmentNotification
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}
 
/**
* Handle the event.
*
* @param \App\Events\OrderShipped $event
* @return void
*/
public function handle(OrderShipped $event)
{
// Access the order using $event->order...
}
}

شنوندگان رویداد شما همچنین ممکن است هر گونه وابستگی را که به سازنده خود نیاز دارند تایپ کنند. همه شنوندگان رویداد از طریق ظرف سرویس لاراول حل می شوند ، بنابراین وابستگی ها به طور خودکار تزریق می شوند.

توقف انتشار یک رویداد

گاهی اوقات، ممکن است بخواهید انتشار یک رویداد را برای شنوندگان دیگر متوقف کنید. شما می توانید این کار را با بازگشت false از روش شنونده خود انجام دهید handle .

شنوندگان رویداد در صف

در صورتی که شنونده شما بخواهد کارهای کندی مانند ارسال ایمیل یا درخواست HTTP انجام دهد، قرار دادن شنوندگان در صف می تواند مفید باشد. قبل از شروع کار با شنوندگان در صف، مطمئن شوید که صف خود را پیکربندی کرده و یک شنونده صف را در سرور یا محیط توسعه محلی خود راه اندازی کنید.

برای تعیین اینکه شنونده باید در صف قرار گیرد، ShouldQueue رابط را به کلاس listener اضافه کنید. شنوندگان تولید شده توسط event:generate دستور Artisan قبلاً این رابط را به فضای نام فعلی وارد کرده اند، بنابراین می توانید بلافاصله از آن استفاده کنید:

<?php
 
namespace App\Listeners;
 
use App\Events\OrderShipped;
use Illuminate\Contracts\Queue\ShouldQueue;
 
class SendShipmentNotification implements ShouldQueue
{
//
}

خودشه! اکنون، هنگامی که این شنونده برای یک رویداد فراخوانی می شود، به طور خودکار توسط توزیع کننده رویداد با استفاده از سیستم صف لاراول در صف قرار می گیرد . اگر هنگام اجرای شنونده توسط صف، هیچ استثنایی وجود نداشته باشد، پس از اتمام پردازش، کار در صف به طور خودکار حذف می شود.

سفارشی کردن اتصال صف و نام صف

اگر می‌خواهید اتصال صف، نام صف یا زمان تأخیر صف شنونده رویداد را سفارشی کنید، می‌توانید $connection , $queue یا $delay ویژگی‌ها را در کلاس شنونده خود تعریف کنید:

<?php
 
namespace App\Listeners;
 
use App\Events\OrderShipped;
use Illuminate\Contracts\Queue\ShouldQueue;
 
class SendShipmentNotification implements ShouldQueue
{
/**
* The name of the connection the job should be sent to.
*
* @var string|null
*/
public $connection = 'sqs';
 
/**
* The name of the queue the job should be sent to.
*
* @var string|null
*/
public $queue = 'listeners';
 
/**
* The time (seconds) before the job should be processed.
*
* @var int
*/
public $delay = 60;
}

شنوندگان در صف مشروط

گاهی اوقات، ممکن است لازم باشد تعیین کنید که آیا شنونده باید بر اساس برخی از داده هایی که فقط در زمان اجرا در دسترس هستند در صف قرار گیرد یا خیر. برای انجام این کار، shouldQueue ممکن است روشی به شنونده اضافه شود تا تعیین کند آیا شنونده باید در صف قرار گیرد و همزمان اجرا شود:

<?php
 
namespace App\Listeners;
 
use App\Events\OrderPlaced;
use Illuminate\Contracts\Queue\ShouldQueue;
 
class RewardGiftCard implements ShouldQueue
{
/**
* Reward a gift card to the customer.
*
* @param \App\Events\OrderPlaced $event
* @return void
*/
public function handle(OrderPlaced $event)
{
//
}
 
/**
* Determine whether the listener should be queued.
*
* @param \App\Events\OrderPlaced $event
* @return bool
*/
public function shouldQueue(OrderPlaced $event)
{
return $event->order->subtotal >= 5000;
}
}

دسترسی دستی به صف

delete اگر نیاز دارید که به صورت دستی به کارها و روش‌های صف زیربنایی شنونده دسترسی داشته باشید release ، ممکن است این کار را با استفاده از ویژگی انجام دهید Illuminate\Queue\InteractsWithQueue . این ویژگی به طور پیش‌فرض در شنوندگان تولید شده وارد می‌شود و دسترسی به این روش‌ها را فراهم می‌کند:

<?php
 
namespace App\Listeners;
 
use App\Events\OrderShipped;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
 
class SendShipmentNotification implements ShouldQueue
{
use InteractsWithQueue;
 
/**
* Handle the event.
*
* @param \App\Events\OrderShipped $event
* @return void
*/
public function handle(OrderShipped $event)
{
if (true) {
$this->release(30);
}
}
}

رسیدگی به مشاغل ناموفق

گاهی اوقات ممکن است شنوندگان رویداد در صف شما شکست بخورند. اگر شنونده در صف از حداکثر تعداد تلاشی که توسط کارگر صف شما تعریف شده است بیشتر شود، failed روش در شنونده شما فراخوانی می شود. متد failed نمونه رویداد و استثنایی که باعث شکست شده است را دریافت می کند:

<?php
 
namespace App\Listeners;
 
use App\Events\OrderShipped;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
 
class SendShipmentNotification implements ShouldQueue
{
use InteractsWithQueue;
 
/**
* Handle the event.
*
* @param \App\Events\OrderShipped $event
* @return void
*/
public function handle(OrderShipped $event)
{
//
}
 
/**
* Handle a job failure.
*
* @param \App\Events\OrderShipped $event
* @param \Exception $exception
* @return void
*/
public function failed(OrderShipped $event, $exception)
{
//
}
}

اعزام رویدادها

برای ارسال یک رویداد، می توانید نمونه ای از رویداد را به event کمک کننده ارسال کنید. کمک کننده رویداد را برای همه شنوندگان ثبت نام شده خود ارسال می کند. از آنجایی که event Helper به صورت جهانی در دسترس است، می توانید از هر نقطه در برنامه خود با آن تماس بگیرید:

<?php
 
namespace App\Http\Controllers;
 
use App\Events\OrderShipped;
use App\Http\Controllers\Controller;
use App\Order;
 
class OrderController extends Controller
{
/**
* Ship the given order.
*
* @param int $orderId
* @return Response
*/
public function ship($orderId)
{
$order = Order::findOrFail($orderId);
 
// Order shipment logic...
 
event(new OrderShipped($order));
}
}

هنگام آزمایش، می‌توان گفت که برخی رویدادها بدون تحریک شنوندگان ارسال شده‌اند. کمک‌کننده‌های تست داخلی لاراول، آن را بسیار جذاب کرده است.

مشترکین رویداد

نوشتن مشترکین رویداد

مشترکین رویداد کلاس هایی هستند که ممکن است در چندین رویداد از درون خود کلاس مشترک شوند و به شما امکان می دهند چندین کنترل کننده رویداد را در یک کلاس واحد تعریف کنید. مشترکین باید subscribe روشی را تعریف کنند که به یک نمونه توزیع کننده رویداد ارسال می شود. برای ثبت شنوندگان رویداد می توانید listen متد موجود در توزیع کننده داده شده را فراخوانی کنید:

<?php
 
namespace App\Listeners;
 
class UserEventSubscriber
{
/**
* Handle user login events.
*/
public function handleUserLogin($event) {}
 
/**
* Handle user logout events.
*/
public function handleUserLogout($event) {}
 
/**
* Register the listeners for the subscriber.
*
* @param \Illuminate\Events\Dispatcher $events
*/
public function subscribe($events)
{
$events->listen(
'Illuminate\Auth\Events\Login',
'App\Listeners\UserEventSubscriber@handleUserLogin'
);
 
$events->listen(
'Illuminate\Auth\Events\Logout',
'App\Listeners\UserEventSubscriber@handleUserLogout'
);
}
}

ثبت نام مشترکین رویداد

پس از نوشتن مشترک، آماده ثبت آن در دیسپچر رویداد هستید. شما می توانید مشترکین را با استفاده از $subscribe ملک در EventServiceProvider . به عنوان مثال، بیایید UserEventSubscriber به لیست اضافه کنیم:

<?php
 
namespace App\Providers;
 
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
 
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
//
];
 
/**
* The subscriber classes to register.
*
* @var array
*/
protected $subscribe = [
'App\Listeners\UserEventSubscriber',
];
}