
ปัญหา "Login หมดอายุเอง" หรือ "ต้อง Login ใหม่ทุกครั้ง" เป็นเรื่องที่พบบ่อยมากบน Shared Hosting สาเหตุหลักมาจากพฤติกรรมของ PHP Session ที่บน Shared Hosting ทำงานต่างจาก VPS หรือ Server ส่วนตัว บทความนี้จะอธิบายสาเหตุและวิธีแก้ปัญหาทีละขั้นตอน
ทำไม PHP Session ถึงหมดอายุเร็วบน Shared Hosting
Session GC รันโดย User อื่น
Shared Hosting แชร์ Session Directory กัน เมื่อ User อื่น Trigger GC (Garbage Collection) อาจลบ Session ของ User คุณได้
session.gc_maxlifetime สั้นเกิน
ค่าเริ่มต้น 1440 วินาที (24 นาที) ถ้าไม่มี Activity Session จะหมดอายุและถูกลบ
Session Path ผิดหรือไม่มีสิทธิ์
Session ไม่ถูกเขียนได้เพราะ Path ไม่มีสิทธิ์ เมื่อ PHP อ่านกลับจะไม่เจอ Session
Cookie Domain/Path ผิด
Cookie ที่เก็บ Session ID ถูกตั้งค่าผิด ทำให้ Browser ไม่ส่ง Cookie กลับไปให้ Server
ตรวจสอบ Session Settings ปัจจุบัน
สร้างไฟล์ทดสอบ session_info.php เพื่อดูค่าที่ Server ใช้อยู่จริง (ลบทิ้งหลังใช้งาน):
วิธีแก้ที่ 1 — ตั้งค่าใน php.ini หรือ .htaccess
วิธีง่ายที่สุดคือเพิ่มค่าใน .htaccess หรือ php.ini ของโปรเจกต์:
ค่า 86400 = 24 ชั่วโมง: ปรับตามความต้องการของแอป — แนะนำไม่เกิน 86400 (1 วัน) สำหรับแอปทั่วไป
วิธีแก้ที่ 2 — ย้าย Session ไปโฟลเดอร์ส่วนตัว
ปัญหาหลักบน Shared Hosting คือ GC ของ User อื่นลบ Session คุณ แก้ได้โดยย้าย Session ไปเก็บในโฟลเดอร์ที่ User อื่นเข้าไม่ถึง:
ระวัง: โฟลเดอร์ sessions/ ต้องไม่เข้าถึงได้จาก Web ให้เพิ่ม deny from all ใน sessions/.htaccess หรือวางโฟลเดอร์นอก public_html
วิธีแก้ที่ 3 — เก็บ Session ในฐานข้อมูล (แนะนำสำหรับแอปสำคัญ)
วิธีที่แข็งแกร่งที่สุดและแก้ปัญหา GC ได้ถาวรคือเก็บ Session ใน MySQL:
วิธีแก้ที่ 4 — ตั้งค่า Cookie ให้ถูกต้อง
ถ้า Session ยังคงอยู่แต่ Browser ไม่ส่ง Cookie กลับ ตรวจสอบการตั้งค่า Cookie:
วิธีแก้ที่ 5 — Regenerate Session ID เพื่อความปลอดภัย
ควร Regenerate Session ID ทุกครั้งที่ Login สำเร็จ เพื่อป้องกัน Session Fixation Attack:
ตรวจสอบด้วย Debug Script
รีเฟรชหน้าซ้ำๆ ถ้า Counter เพิ่มขึ้นต่อเนื่องแปลว่า Session ทำงานปกติ ถ้า Counter รีเซ็ตเป็น 1 ทุกครั้งแปลว่า Session ยังมีปัญหา
สรุปแนวทาง: แอปที่มีผู้ใช้น้อย → ย้าย Session ไปโฟลเดอร์ส่วนตัว (วิธีที่ 2) แอปที่มีผู้ใช้มาก → เก็บ Session ใน MySQL (วิธีที่ 3) ทั้งคู่ควรใช้ร่วมกับการตั้งค่า Cookie ที่ปลอดภัย (วิธีที่ 4)
การเปรียบเทียบ Session Storage แต่ละแบบ
แต่ละวิธีการจัดเก็บ Session มีข้อดีข้อเสียต่างกัน การเลือกให้เหมาะกับขนาดและลักษณะของแอปจะช่วยแก้ปัญหาได้อย่างยั่งยืน
| วิธีจัดเก็บ | เหมาะกับ | ข้อดี | ข้อจำกัด |
|---|---|---|---|
| ไฟล์ระบบ (Default) | Local / Dev | ตั้งค่าง่าย ไม่ต้องใช้ DB | GC ของ User อื่นลบ Session ได้ |
| โฟลเดอร์ส่วนตัว | Shared Hosting แอปขนาดเล็ก | แก้ GC ข้าม User ได้ ติดตั้งง่าย | ยังพึ่งระบบไฟล์ ถ้า Disk เต็มจะมีปัญหา |
| MySQL Database | แอป Production ที่มีผู้ใช้มาก | เสถียรมาก ควบคุม Expiry ได้ดี | เพิ่ม DB Load ต้อง Clean Up Expired |
| Redis / Memcached | VPS / High-Traffic App | เร็วมาก รองรับ Multi-Server | ต้องติดตั้ง Extension เพิ่ม ไม่ใช่ทุก Hosting มี |
Session Security — สิ่งที่ต้องทำควบคู่กับการแก้ปัญหาหมดอายุ
เมื่อแก้ปัญหา Session หมดอายุเร็วแล้ว ควรตรวจสอบความปลอดภัยของ Session ด้วย เพราะ Session ที่อยู่นานขึ้นมีความเสี่ยงด้านความปลอดภัยเพิ่มขึ้นตามไปด้วย
ป้องกัน Session Hijacking
Session Hijacking คือการที่ผู้ไม่หวังดีขโมย Session ID ของผู้ใช้เพื่อปลอมตัวเป็นผู้ใช้นั้น วิธีป้องกันที่สำคัญ:
- บังคับใช้ HTTPS เสมอ — ตั้ง
session.cookie_secure = 1เพื่อให้ Cookie ส่งเฉพาะผ่าน HTTPS - ตั้ง
session.cookie_httponly = 1เพื่อป้องกัน JavaScript เข้าถึง Session Cookie (ลด XSS Risk) - ตรวจ User-Agent และ IP Address ว่าเปลี่ยนไปจากตอน Login หรือไม่
- Regenerate Session ID ทุกครั้งที่สิทธิ์เปลี่ยน (Login, Logout, Privilege Escalation)
ป้องกัน Session Fixation
Session Fixation คือการที่ผู้โจมตีบังคับให้ Victim ใช้ Session ID ที่ผู้โจมตีรู้อยู่แล้ว แก้ได้ง่ายๆ ด้วยคำสั่งเดียว:
ตั้งเวลาหมดอายุ Session แบบ Absolute และ Idle
แทนที่จะพึ่ง gc_maxlifetime เพียงอย่างเดียว ให้ใช้การตรวจสอบเวลาเพิ่มเติมใน Code:
คำถามที่พบบ่อยเกี่ยวกับ PHP Session บน Hosting
เพิ่ม session.gc_maxlifetime แล้วยังหมดอายุเร็วอยู่ เป็นเพราะอะไร?
ปัญหานี้มักเกิดจาก Session GC ของ User อื่นบน Shared Hosting รัน GC ด้วย gc_maxlifetime ของตัวเอง (อาจสั้นกว่า) และลบ Session ของคุณ วิธีแก้ถาวรคือย้าย Session ไปโฟลเดอร์ส่วนตัว (วิธีที่ 2) หรือเก็บใน MySQL (วิธีที่ 3) ซึ่งจะไม่ถูก GC ของคนอื่นกระทบ
WordPress Session ต่างจาก PHP Session ทั่วไปอย่างไร?
WordPress ไม่ใช้ $_SESSION ของ PHP โดยตรง แต่ใช้ Authentication Cookies (wordpress_logged_in_*, wordpress_*) แทน ปัญหา "Login หมดอายุ" ใน WordPress จึงมักเกิดจาก Cookie Domain ผิด, HTTPS/HTTP ผสม (Mixed Content), หรือ WordPress Secret Keys ใน wp-config.php ถูก Regenerate แก้โดยตั้ง COOKIEPATH และ COOKIE_DOMAIN ใน wp-config.php ให้ถูกต้อง
ใช้ Redis เก็บ Session ได้บน Shared Hosting ไหม?
ขึ้นอยู่กับว่า Hosting รองรับ PHP Extension phpredis หรือ predis หรือไม่ AsiaGB Hosting บางแพ็กเกจมี Redis Extension ให้ ตรวจสอบได้จาก phpinfo() หรือสอบถาม Support สำหรับแอปที่ต้องการ Redis แนะนำให้เลื่อนไปใช้ VPS ซึ่งสามารถติดตั้ง Redis Service ได้เต็มรูปแบบ
ตรวจสอบและ Monitor PHP Session บน Production
หลังจากแก้ปัญหา Session หมดอายุแล้ว ควรมีระบบ Monitor เพื่อให้แน่ใจว่า Session ทำงานถูกต้องในระยะยาว โดยเฉพาะเมื่อมีการ Update PHP Version หรือ Plugin ที่อาจเปลี่ยน Session Settings โดยไม่ตั้งใจ
สร้างหน้า Session Health Check
สร้างหน้า PHP ที่เข้าถึงได้เฉพาะ Admin เพื่อตรวจสอบ Session Settings ในแต่ละ Deploy:
ตรวจ Session ใน MySQL แบบ Real-time
ถ้าใช้ MySQL Session Handler สามารถ Query ดู Session ที่กำลัง Active อยู่และ Session ที่ Expire แล้วแต่ยังไม่ถูกลบ:
สัญญาณว่า Session ยังมีปัญหา
หลังแก้ไขแล้ว ควรตรวจสอบสัญญาณต่อไปนี้เพื่อยืนยันว่าปัญหาหายจริง:
- ผู้ใช้ไม่ถูก Logout โดยไม่มีสาเหตุระหว่างใช้งานปกติ
- Counter ใน Debug Script เพิ่มขึ้นต่อเนื่องโดยไม่รีเซ็ต
- Error Log ไม่มีข้อความเกี่ยวกับ Session เช่น
session_start(): Failed to read session data - ขนาดโฟลเดอร์
sessions/หรือตารางphp_sessionsใน MySQL ไม่โตขึ้นเรื่อยๆ โดยไม่มีการลบ
ถ้ายังพบปัญหาหลังทำตามทุกขั้นตอน ให้ส่ง Ticket ให้ Support พร้อมแนบ Output ของ session_info.php และ Error Log ล่าสุด เพื่อให้ทีมงานช่วยตรวจสอบ Config ระดับ Server ที่อาจ Override ค่าที่ตั้งไว้ นอกจากนี้ควรตรวจว่า php.ini ระดับ Server ไม่ได้ Lock ค่า session ไว้ด้วย Directive session.gc_maxlifetime เพราะในบาง Hosting ค่าจาก .htaccess จะไม่สามารถ Override ค่า Server ได้ถ้าถูกตั้งเป็น PHP_INI_SYSTEM
เพิ่ม Cron Job ทำความสะอาด MySQL Session
เพิ่ม Cron Job ใน DirectAdmin เพื่อลบ Session ที่หมดอายุออกจากฐานข้อมูลทุกวัน ลด Database Size ที่ไม่จำเป็น:
Hosting รองรับ PHP Session เต็มรูปแบบ
AsiaGB Hosting รองรับ PHP Session Handler แบบกำหนดเอง, MySQL, และ Session Path ส่วนตัว เริ่มต้น 500 บาท/ปี
ดูแพ็กเกจ Hosting