สาเหตุหลักที่ $this->session_lab_id มีค่าเป็น null คือ การดึงข้อมูล session ใน __construct() ของ Controller จะทำงานก่อนที่ Middleware ของ Session จะเริ่มทำงาน ครับ
พูดง่ายๆ คือ ตอนที่ __construct() ถูกเรียก, Laravel ยังไม่ได้โหลดข้อมูล session ของ request ปัจจุบันเข้ามา ทำให้ session()->get(...) ได้ค่า null กลับไปเสมอ
คำอธิบายปัญหา
ลำดับการทำงานของ Laravel Request Lifecycle เป็นแบบนี้ครับ:
- Request เข้ามาที่
index.php - สร้าง instance ของแอปพลิเคชัน
- Kernel จัดการ Request
- Service Provider โหลดเข้ามา
- Controller ถูกสร้างขึ้น (
__constructทำงาน ณ จุดนี้) ⬅️ - Middleware ถูกรัน (เช่น
StartSessionที่ทำให้ session() ใช้งานได้) ⬅️ - Request ถูกส่งไปที่ Method ใน Controller (เช่น
orderPt())
จะเห็นว่า __construct (ข้อ 5) ทำงานก่อนที่ StartSession (ข้อ 6) จะทำงานครับ
วิธีแก้ไข : ใช้ Middleware ใน Constructor (วิธีที่แนะนำสำหรับทั้ง Controller)
ถ้าคุณต้องการให้ session_lab_id พร้อมใช้งานในทุกเมธอดของ Controller นี้โดยไม่ต้องเขียนซ้ำๆ ให้ใช้ Middleware แบบ Closure ใน __construct ครับ
แก้ไข __construct() ดังนี้:
public function __construct()
{
$this->middleware(function ($request, $next) {
// โค้ดในนี้จะทำงานหลังจาก Middleware StartSession ทำงานแล้ว
$this->session_lab_id = session()->get(‘selected_lab_id’);
// Optional: สามารถเพิ่มเงื่อนไขเพื่อตรวจสอบค่าได้
if (is_null($this->session_lab_id)) {
// อาจจะ redirect หรือทำอย่างอื่นถ้าไม่มี session
// return redirect(‘/select-lab’);
}
return $next($request);
});
}