EST. 2026 — บันทึกงานเซิร์ฟเวอร์จริง SYSADMIN · SECURITY · AI · DIRECTADMIN เล่มที่ 01
THE SYSADMIN ALMANAC
หน้าหลัก / DirectAdmin / WordPress ขึ้น 500 บางหน้า แต่ debug.log ว่าง — fatal จริงอยู่ที่ apache log
DirectAdmin

WordPress ขึ้น 500 บางหน้า แต่ debug.log ว่าง — fatal จริงอยู่ที่ apache log

โดย Ton-Or ·8 ก.ค. 2026·อ่าน 8 นาที
WordPress ขึ้น 500 บางหน้า แต่ debug.log ว่าง — fatal จริงอยู่ที่ apache log

log ว่างไม่ได้แปลว่าไม่มี error — fatal ที่เกิดก่อนระบบ logging ของ WordPress พร้อมทำงาน จะไม่มีวันโผล่ใน debug.log เคสนี้เป็นตัวอย่างที่ดีว่าความจริงสุดท้ายอยู่ที่ log ของ web server เสมอ

พอดีมีเว็บ WordPress ของหน่วยงานหนึ่งอาการประหลาดครับ: หน้าแรกปกติ หน้าบทความปกติ แต่เฉพาะหน้า portfolio ทุกหน้า (/portfolio-items/อะไรก็ตาม/) ขึ้น 500 หมด

ผมเปิด WP_DEBUG_LOG รอไว้แล้วกดหน้า 500 ซ้ำ — debug.log ว่างเปล่า ไม่มีอะไรเข้าเลย ตรงนี้แหละที่หลายคนหลงทาง เพราะสัญชาตญาณบอกว่า "log ว่าง = ไม่มี error" จริงๆ คือ:

กับดักของ log ว่าง

Fatal ที่เกิดตอน theme กำลัง render เกิดก่อนที่ระบบ logging ของ WP จะพร้อมทำงาน — debug.log เลยไม่มีวันเห็นมัน อย่าเพิ่งสรุปว่าไม่มี error

fatal ตัวจริงอยู่ใน apache error log

โฮสติ้งที่รัน PHP-FPM ผ่าน apache (mod_proxy_fcgi) จะมี log ต่อโดเมนอยู่ที่:

tail -50 /var/log/httpd/domains/example-site.org.error.log

เจอทันที:

[proxy_fcgi:error] AH01071: Got error 'PHP message: PHP Fatal error:
Uncaught Error: Call to undefined method Avada_Layout::add_class()
in /home/user/domains/example-site.org/public_html/wp-content/themes/my-child-theme/single-avada_portfolio.php:18'

ชัดเลยครับ — child theme มีไฟล์ single-avada_portfolio.php ที่เรียก method ที่ไม่มีอยู่แล้ว

เริ่มโหลด WordPressหน้า portfoliotheme renderfatal เกิดตรงนี้WP logging พร้อมไปไม่ถึงตรงนี้ถูกบันทึกที่นี่apache error logproxy_fcgi: PHP Fatal errorไม่มีอะไรเข้าdebug.logว่างเปล่าความจริงสุดท้ายอยู่ที่ log ของ web server
fatal ตอน theme render เกิดก่อนที่ WP logging จะพร้อม debug.log เลยว่าง ต้องดู apache error log ที่ proxy_fcgi บันทึกไว้

เว็บที่ log เยอะๆ หาตัวการแบบเป็นระบบได้ด้วยบรรทัดเดียว:

grep 'Fatal' /var/log/httpd/domains/example-site.org.error.log \
  | grep -oE '/wp-content/(plugins|themes)/[^/ ]+' | sort | uniq -c | sort -rn

ได้คำตอบทันทีว่า fatal กระจุกอยู่ theme/plugin ตัวไหน

ทำไมถึงพัง — โรคประจำตัวของ child theme

ไล่ประวัติแล้วเรื่องเป็นแบบนี้ครับ: คนทำเว็บเมื่อ 2 ปีก่อนก๊อปไฟล์ template จาก parent theme (Avada) มาแก้ใน child theme ซึ่งเป็นวิธีมาตรฐานของ WP ไม่ผิดอะไร — แต่ไฟล์ก๊อปนั้นเรียก internal API ของ Avada เวอร์ชันนั้น (Avada()->layout->add_class())

ระเบิดเวลา child themeก๊อป templateจาก parent รุ่นเก่า→parent อัปเดตลบ method ทิ้ง→ไฟล์ก๊อปไม่มีใครอัปเดต→fatal 500ทุกหน้าที่ใช้ template

เวลาผ่านไป Avada อัปเดตมาเรื่อยๆ จนเวอร์ชันปัจจุบันลบ method นั้นทิ้ง — template อื่นของ parent ถูกอัปเดตตาม แต่ไฟล์ก๊อปใน child theme ไม่มีใครแตะ หน้าไหนใช้ template นั้น = fatal ทันที

เช็ค blast radius ก่อนแก้ — child theme เรียก API ที่ตายแล้วอีกกี่ไฟล์:

grep -rln 'add_class\|add_style' wp-content/themes/my-child-theme/
# โชคดี: ไฟล์เดียว

วิธีแก้ที่เลือก: rename ให้ fallback

ผมไม่แก้โค้ดในไฟล์ทีละ method ครับ เพราะไฟล์ 11KB นั้นอาจเรียก API ที่ถูกลบไปอีกหลายจุด แก้ตัวหนึ่งเจอตัวถัดไป ไม่จบ ทางที่เสถียรกว่า:

cd wp-content/themes/my-child-theme
mv single-avada_portfolio.php single-avada_portfolio.php.disabled-2026-07-04

หลักการ: template hierarchy ของ WP เมื่อไม่เจอไฟล์ใน child จะ fallback ไป parent — Avada รุ่นใหม่จัดการ portfolio ผ่านระบบ template ของตัวเองอยู่แล้ว ผลคือหน้า portfolio กลับมา 200 เนื้อหาแสดงครบ เพียง layout เป็นแบบ default ของ Avada แทนแบบ custom เก่า (ซึ่งเจ้าของเว็บโอเค)

ข้อดีคือ reversible 100% — อยากได้ custom layout คืนก็ mv กลับแล้วค่อยนั่ง port โค้ดตาม API ใหม่ ตามสะดวก

เปิด WP_DEBUG อย่างปลอดภัยบนเว็บ production

แถมท้ายครับ เวลาต้อง debug เว็บจริงที่มีคนใช้งาน:

// wp-config.php — backup ไฟล์ก่อนแก้เสมอ
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);   // สำคัญ! อย่าโชว์ error ให้คนเข้าเว็บเห็น

แล้ว php -l wp-config.php ก่อนทุกครั้ง — พลาด syntax ตัวเดียวเว็บขาวทั้งเว็บ และอย่าลืมว่าตามที่เล่าข้างบน fatal ระดับ theme-load อาจไม่เข้า debug.log อยู่ดี apache error log คือแหล่งความจริงสุดท้าย

สรุปเป็นเช็คลิสต์

  1. 500 เฉพาะบางประเภทหน้า + debug.log ว่าง = fatal เกิดก่อน WP logging — อย่าเชื่อ log ว่าง
  2. ความจริงอยู่ที่ /var/log/httpd/domains/<domain>.error.log — มองหา proxy_fcgi + PHP Fatal
  3. grep -oE '/wp-content/...' | sort | uniq -c หา culprit
  4. child theme ที่ก๊อป template จาก parent = ระเบิดเวลาทุกครั้งที่ parent อัปเดตใหญ่
  5. แก้ด้วยการ rename ให้ fallback ก่อน (reversible) ค่อยตัดสินใจ port โค้ด

ส่วนตัวผมเจอโรค child theme แบบนี้มาหลายเว็บแล้ว ใครรับดูแลเว็บ WP ต่อจากคนอื่น ไล่เช็คไฟล์ก๊อปใน child theme ไว้ก่อนเลยครับ ตรงไหนผมอธิบายตกหล่นหรือพิมพ์ผิด เดี๋ยวกลับมาแก้เพิ่มให้ภายหลังครับ

อยากให้เราทำให้ไหม?

ให้เราช่วยติดตั้ง ตั้งค่า ย้ายระบบ หรือแก้ปัญหาเซิร์ฟเวอร์ เพื่อให้คุณมีเวลาไปทำงานที่สำคัญกว่า

คุยเรื่องงานกับเรา

เคยเจองานแบบนี้ไหม? ติดตรงไหน?

มาแลกวิธีกันต่อในบอร์ด LinuxThai

→ คุยต่อในบอร์ด

ความคิดเห็น 0

ยังไม่มีความคิดเห็น — เป็นคนแรกเลย