Laravel Events และ Listeners ปี 2026: สถาปัตยกรรม Event-Driven และคำถามสัมภาษณ์
คู่มือฉบับสมบูรณ์เกี่ยวกับ Laravel events และ listeners สำหรับสถาปัตยกรรม event-driven เรียนรู้ observer pattern, queued listeners, event subscribers และคำถามสัมภาษณ์ทางเทคนิค

Laravel events และ listeners ใช้งาน observer pattern แยก component ออกจากกันโดยให้ส่วนต่างๆ ของแอปพลิเคชันตอบสนองต่อการกระทำโดยไม่ต้องพึ่งพากันโดยตรง เมื่อผู้ใช้สั่งซื้อ event OrderShipped จะถูกเรียก และ listener แยกต่างหากจัดการการแจ้งเตือน การวิเคราะห์ และการอัปเดตสินค้าคงคลังอย่างอิสระ
Laravel 12 ค้นหา listener ใน app/Listeners โดยอัตโนมัติ class ใดๆ ที่มี method handle หรือ __invoke พร้อม type-hint ไปยัง event class จะถูกลงทะเบียนโดยอัตโนมัติ ไม่ต้องมีไฟล์กำหนดค่า
วิธีการทำงานของ Event Discovery ใน Laravel 12
ตั้งแต่ Laravel 11 EventServiceProvider ถูกลบออก Laravel สแกนไดเรกทอรี Listeners และใช้ reflection เพื่อกำหนดว่า event ใดที่ listener แต่ละตัวตอบสนองตาม type hint ใน method signature ของ handle
<?php
namespace App\Listeners;
use App\Events\OrderShipped;
class SendOrderConfirmation
{
public function handle(OrderShipped $event): void
{
// ส่งอีเมลยืนยันไปยัง $event->order->user
}
}Listener ด้านบนถูกลงทะเบียนโดยอัตโนมัติสำหรับ event OrderShipped ไม่ต้อง binding ด้วยตนเองใน service provider สิ่งนี้ลด boilerplate และรักษาความสัมพันธ์ event-listener ให้ใกล้กับโค้ดที่ implement
เพื่อตรวจสอบ listener ที่ลงทะเบียน ให้รัน php artisan event:list สำหรับ production ให้ cache manifest event ด้วย php artisan event:cache เพื่อข้ามการสแกนไดเรกทอรีในแต่ละ request
การสร้าง Events และ Listeners ด้วย Artisan
Laravel มีคำสั่ง Artisan สำหรับสร้าง scaffold events และ listeners:
# สร้าง event class
php artisan make:event OrderShipped
# สร้าง listener ที่เชื่อมโยงกับ event
php artisan make:listener SendShipmentNotification --event=OrderShippedEvent class ที่สร้างขึ้นใช้สาม trait: Dispatchable สำหรับ method static dispatch(), InteractsWithSockets สำหรับ broadcasting และ SerializesModels สำหรับ serialize Eloquent model เมื่อ listener ถูก queue
<?php
namespace App\Events;
use App\Models\Order;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Queue\SerializesModels;
class OrderShipped
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public function __construct(
public Order $order,
) {}
}Event class เป็น container ข้อมูล มันเก็บ model Order และไม่มีอะไรอื่น Business logic อยู่ใน listener ไม่ใช่ใน event
การ Dispatch Events จาก Controllers และ Services
Dispatch event โดยใช้ method static dispatch() บน event class:
<?php
namespace App\Http\Controllers;
use App\Events\OrderShipped;
use App\Models\Order;
use Illuminate\Http\Request;
class OrderController extends Controller
{
public function ship(Request $request, Order $order)
{
// logic การจัดส่งที่นี่...
OrderShipped::dispatch($order);
return redirect()->route('orders.index');
}
}สำหรับ dispatch แบบมีเงื่อนไข ใช้ dispatchIf() หรือ dispatchUnless():
// Dispatch เฉพาะเมื่อ order มีหมายเลข tracking
OrderShipped::dispatchIf($order->tracking_number !== null, $order);พร้อมที่จะพิชิตการสัมภาษณ์ Laravel แล้วหรือยังครับ?
ฝึกฝนด้วยตัวจำลองแบบโต้ตอบ, flashcards และแบบทดสอบเทคนิคครับ
Queued Listeners สำหรับการดำเนินการที่ช้า
Listener ที่ส่งอีเมล เรียก API ภายนอก หรือทำการคำนวณหนักควรทำงานแบบ asynchronous implement ShouldQueue เพื่อผลัก listener ไปยัง queue:
<?php
namespace App\Listeners;
use App\Events\OrderShipped;
use Illuminate\Contracts\Queue\ShouldQueue;
class SendShipmentNotification implements ShouldQueue
{
public $queue = 'notifications';
public $delay = 60; // รอ 60 วินาทีก่อนประมวลผล
public function handle(OrderShipped $event): void
{
// ส่งการแจ้งเตือนไปยัง $event->order->user
}
}ปรับแต่ง connection และชื่อ queue ด้วย property $connection และ $queue หรือใช้ method runtime:
public function viaConnection(): string
{
return 'redis';
}
public function viaQueue(): string
{
return $this->event->order->priority === 'high'
? 'high-priority'
: 'default';
}Conditional Queueing ด้วย shouldQueue
บางครั้ง listener ควร queue ตามข้อมูล event เท่านั้น:
public function shouldQueue(OrderShipped $event): bool
{
// Queue เฉพาะ order ที่มากกว่า 3,000 บาท
return $event->order->total >= 3000;
}Database Transactions และ Event Timing
Queued listener ที่ถูก dispatch ภายใน transaction อาจประมวลผลก่อนที่ transaction จะ commit ทำให้เกิดข้อผิดพลาดข้อมูลหายไป มีสองวิธีแก้ไข:
1. กำหนดค่าทั่วไป ใน config/queue.php:
'connections' => [
'redis' => [
'after_commit' => true,
],
],2. ต่อ listener ด้วย ShouldQueueAfterCommit:
use Illuminate\Contracts\Queue\ShouldQueueAfterCommit;
class UpdateInventory implements ShouldQueueAfterCommit
{
public function handle(OrderShipped $event): void
{
// ปลอดภัยที่จะ query order, transaction ได้ commit แล้ว
}
}สำหรับ event เอง implement ShouldDispatchAfterCommit บน event class:
use Illuminate\Contracts\Events\ShouldDispatchAfterCommit;
class OrderShipped implements ShouldDispatchAfterCommit
{
// Event จะ dispatch หลังจาก transaction commit เท่านั้น
}Unique Listeners เพื่อป้องกันการซ้ำ
Interface ShouldBeUnique ป้องกัน listener ซ้ำจากการเข้า queue ขณะที่มีตัวหนึ่งกำลังประมวลผล:
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
class ProcessLicenseKey implements ShouldQueue, ShouldBeUnique
{
public $uniqueFor = 3600; // Lock หมดอายุหลัง 1 ชั่วโมง
public function uniqueId(LicensePurchased $event): string
{
return 'license:' . $event->license->id;
}
public function handle(LicensePurchased $event): void
{
// สร้างและกำหนด license key
}
}หาก license ID เดียวกันเรียก event หลายครั้งอย่างรวดเร็ว เฉพาะ listener ตัวแรกเท่านั้นที่ประมวลผล ความพยายามต่อมาพบว่า lock ถูกถือไว้และข้าม queueing
Event Subscribers สำหรับ Events ที่เกี่ยวข้อง
เมื่อ event หลายตัวที่เกี่ยวข้องใช้ logic การจัดการร่วมกัน event subscriber จัดกลุ่ม handler ในคลาสเดียว:
<?php
namespace App\Listeners;
use Illuminate\Auth\Events\Login;
use Illuminate\Auth\Events\Logout;
use Illuminate\Events\Dispatcher;
class UserActivitySubscriber
{
public function handleLogin(Login $event): void
{
// บันทึก login สำเร็จ, อัปเดต timestamp last_login
}
public function handleLogout(Logout $event): void
{
// บันทึก logout, ล้างข้อมูล session
}
public function subscribe(Dispatcher $events): array
{
return [
Login::class => 'handleLogin',
Logout::class => 'handleLogout',
];
}
}Subscriber ปฏิบัติตามกฎ automatic discovery หาก method handler อยู่ใน subscriber class พร้อมพารามิเตอร์ที่ type-hint อย่างถูกต้อง Laravel จะลงทะเบียนโดยอัตโนมัติ
การฟัง Multiple Events ด้วย Union Types
Listener เดียวสามารถตอบสนองต่อ event หลายประเภทโดยใช้ PHP 8 union types:
public function handle(OrderShipped|OrderCancelled $event): void
{
match (true) {
$event instanceof OrderShipped => $this->notifyShipped($event),
$event instanceof OrderCancelled => $this->notifyCancelled($event),
};
}Pattern นี้ทำงานได้ดีสำหรับการแจ้งเตือนที่ปฏิบัติตาม logic ที่คล้ายกันในประเภท event ที่แตกต่างกัน
การเลื่อน Events ด้วย Event::defer
Laravel 12 แนะนำ Event::defer() เพื่อเลื่อนการ dispatch event จนกว่า code block จะเสร็จสมบูรณ์ สิ่งนี้รับประกันว่า listener มีสิทธิ์เข้าถึง record ที่เกี่ยวข้องทั้งหมด:
use Illuminate\Support\Facades\Event;
Event::defer(function () {
$user = User::create(['name' => 'John']);
$user->posts()->create(['title' => 'Welcome']);
});
// Event สำหรับการสร้างทั้ง User และ Post dispatch ที่นี่หาก exception เกิดขึ้นภายใน closure event ที่เลื่อนจะไม่ถูก dispatch
เริ่มฝึกซ้อมเลย!
ทดสอบความรู้ของคุณด้วยตัวจำลองสัมภาษณ์และแบบทดสอบเทคนิคครับ
คำถามสัมภาษณ์เกี่ยวกับ Laravel Events และ Listeners
การสัมภาษณ์ทางเทคนิคมักทดสอบความเข้าใจสถาปัตยกรรม event-driven นี่คือคำถามที่แยกแยะ Laravel developer ที่มีประสบการณ์:
Q: Laravel 12 ลงทะเบียน event listener อย่างไรโดยไม่มี EventServiceProvider?
Laravel สแกน app/Listeners โดยใช้ reflection มันอ่าน type hint บน method handle() หรือ __invoke() เพื่อกำหนดว่า event ใดที่ listener แต่ละตัวตอบสนอง Cache manifest ใน production ด้วย php artisan event:cache
Q: เมื่อใดที่ listener ควร implement ShouldQueue?
เมื่อใดก็ตามที่การดำเนินการใช้เวลามากกว่าไม่กี่มิลลิวินาที: ส่งอีเมล เรียก API ภายนอก สร้างรายงาน หรือประมวลผลไฟล์ Listener แบบ synchronous บล็อก HTTP response
Q: ShouldQueueAfterCommit แก้ปัญหาอะไร?
Queued listener อาจประมวลผลก่อนที่ database transaction จะ commit หาก listener query สำหรับ record ที่เพิ่งสร้าง มันจะล้มเหลวเพราะข้อมูลยังไม่ได้ commit ShouldQueueAfterCommit เลื่อนการ dispatch queue จนกว่า transaction จะเสร็จสมบูรณ์
Q: จะป้องกันการประมวลผลซ้ำสำหรับ event เดียวกันได้อย่างไร?
Implement ShouldBeUnique กำหนด uniqueId() เพื่อส่งคืน cache key ตามข้อมูล event Listener รับ atomic lock และ dispatch ที่ซ้ำจะถูกข้ามหาก lock ถูกถือไว้
Q: ความแตกต่างระหว่าง event listener และ event subscriber คืออะไร?
Listener จัดการ event ประเภทเดียว Subscriber คือ class ที่ลงทะเบียน handler สำหรับ event ที่เกี่ยวข้องหลายตัวในที่เดียว มีประโยชน์สำหรับการจัดกลุ่ม event การยืนยันตัวตนหรือ audit logging
ความหมายของ Laravel Events สำหรับแอปพลิเคชันที่ปรับขนาดได้
- Events แยก component ช่วยให้ฟีเจอร์เช่นการแจ้งเตือนและการวิเคราะห์พัฒนาอย่างอิสระ
- Queued listener ส่งต่อการดำเนินการที่ช้า รักษา HTTP response ให้เร็ว
ShouldQueueAfterCommitป้องกัน race condition ระหว่าง queue worker และ database transaction- Automatic discovery ใน Laravel 12 ลบ overhead การกำหนดค่า รักษา logic listener ให้ใกล้กับการ implementation
- Event subscriber รวมการจัดการ event ที่เกี่ยวข้อง ลดการกระจายไฟล์สำหรับ pattern ทั่วไปเช่นการติดตามกิจกรรมผู้ใช้
- โมดูล
/technologies/laravel/interview-questions/events-listenersบน SharpSkill ครอบคลุม pattern เหล่านี้พร้อมคำถามแบบโต้ตอบ
คุณหาบั๊กใน Laravel เจอไหม
โค้ดจริงหนึ่งชิ้น บั๊กที่ซ่อนอยู่หนึ่งจุด วันละหนึ่งครั้ง ลองได้โดยไม่ต้องมีบัญชี

เขียนโดย
Anthony Fillion-Mailletผู้ก่อตั้ง SharpSkill
เป็นนักพัฒนาฟูลสแตกมากว่า 10 ปี ดูแล SharpSkill และรับผิดชอบทุกสิ่งที่เผยแพร่ที่นี่
อัปเดตเมื่อ 20 สิงหาคม 2569
แท็ก
แชร์
บทความที่เกี่ยวข้อง

คำถามสัมภาษณ์ PHP Laravel Developer 2026: คู่มือเตรียมตัวฉบับสมบูรณ์
คู่มือครอบคลุมสำหรับการเตรียมตัวสัมภาษณ์ PHP Laravel developer ปี 2026 ครอบคลุมคำถามเทคนิคเกี่ยวกับ Eloquent ORM, Service Container, authentication, queue และ testing

Laravel 12 ในปี 2026: ฟีเจอร์ใหม่ Starter Kit และคำถามสัมภาษณ์
Laravel 12 นำ starter kit ที่ออกแบบใหม่มาพร้อม React 19, Vue 3, Livewire 4 และ WorkOS AuthKit คู่มือฉบับสมบูรณ์ครอบคลุมฟีเจอร์ใหม่ เส้นทางการอัปเกรด และคำถามสัมภาษณ์สำคัญสำหรับปี 2026

Laravel Middleware เจาะลึก: Authentication, Rate Limiting และ Custom Middleware ฉบับสมบูรณ์
คู่มือเจาะลึก Laravel Middleware ครอบคลุมการทำงานของ Authentication Middleware, Rate Limiting ด้วย Throttle, การสร้าง Custom Middleware และการลงทะเบียน Middleware ใน Laravel 12 พร้อมตัวอย่างโค้ดที่ใช้งานได้จริงในโปรดักชัน