คำตอบสั้น ๆ: ไล่หาสาเหตุและแก้ปัญหาบทความขึ้น 404 หลังเปลี่ยน Permalink ใน WordPress ทั้งบน Apache, Nginx, Plesk และ DirectAdmin
คู่มือนี้อธิบาย WordPress ทีละขั้นตอน พร้อมคำสั่งที่ใช้ได้จริงและปัญหาที่พบบ่อย
หลังจากเปลี่ยนโครงสร้างลิงก์ถาวร (Permalink) ใน WordPress จากแบบ ?p=123 เป็นแบบอ่านง่ายอย่าง /%postname%/ หลายเว็บเจออาการเดียวกัน คือหน้าแรกเปิดได้ปกติ แต่เมื่อคลิกเข้าบทความหรือหน้าใดก็ตามกลับขึ้น 404 Not Found บางครั้งเป็นหน้า 404 ของ WordPress เอง บางครั้งเป็นหน้า 404 เปล่าๆ ของ Web Server
สาเหตุเกือบทั้งหมดมาจากจุดเดียว: Web Server ไม่ได้ส่งคำขอ URL ที่ไม่ใช่ไฟล์จริงไปให้ index.php ของ WordPress จัดการ บทความนี้อธิบายวิธีไล่หาสาเหตุและแก้ไขทั้งบน Apache, Nginx, Plesk และ DirectAdmin
สิ่งที่ต้องเตรียม
- สิทธิ์ผู้ดูแล (Administrator) ในหลังบ้าน WordPress
- สิทธิ์แก้ไขไฟล์ในโฟลเดอร์เว็บ ผ่าน File Manager ของ Plesk/DirectAdmin, SFTP หรือ SSH
- หากเป็น Cloud Server ที่ดูแลเอง ต้องมีสิทธิ์
sudoเพื่อแก้ไฟล์ตั้งค่า Apache หรือ Nginx - สำรองไฟล์
.htaccessหรือไฟล์ตั้งค่า Web Server เดิมไว้ก่อนแก้ทุกครั้ง
ขั้นตอนที่ 1: รู้ก่อนว่าเว็บรันอยู่บน Web Server ตัวไหน
วิธีแก้ต่างกันตาม Web Server จึงควรตรวจให้แน่ใจก่อน รันคำสั่งนี้จากเครื่องใดก็ได้
curl -sI https://example.com/ | grep -i '^server'
ผลลัพธ์ที่มักเห็นคือ Server: Apache, Server: nginx หรือ Server: LiteSpeed สรุปแนวทางได้ดังนี้
| Web Server | อ่านไฟล์ .htaccess หรือไม่ | จุดที่ต้องแก้ |
|---|---|---|
| Apache | อ่าน (ถ้าเปิด AllowOverride) | .htaccess และ mod_rewrite |
| LiteSpeed / OpenLiteSpeed | อ่าน (OpenLiteSpeed ต้องเปิด Auto Load from .htaccess) | .htaccess |
| Nginx ล้วน | ไม่อ่าน | ไฟล์ Server Block (try_files) |
| Nginx หน้า Apache (แบบที่ Plesk และ DirectAdmin ใช้บ่อย) | อ่านผ่าน Apache | .htaccess |
| IIS (Windows Hosting) | ไม่อ่าน | web.config และ URL Rewrite Module |
หมายเหตุ: ค่า Header Server อาจถูกซ่อนหรือแสดงเป็น nginx แม้ด้านหลังจะเป็น Apache ก็ได้ ถ้าไม่แน่ใจให้สอบถามผู้ดูแลระบบหรือดูที่แผงควบคุม
ขั้นตอนที่ 2: บันทึก Permalink ใหม่อีกครั้ง
วิธีที่ง่ายที่สุดและแก้ได้หลายกรณี คือให้ WordPress เขียนกฎ Rewrite ใหม่
- เข้าหลังบ้าน WordPress ไปที่ การตั้งค่า > ลิงก์ถาวร (Settings > Permalinks)
- ไม่ต้องเปลี่ยนอะไร กดปุ่ม บันทึกการเปลี่ยนแปลง (Save Changes)
- ลองเปิดบทความอีกครั้ง
ถ้าบนหน้าจอมีข้อความว่า WordPress เขียนไฟล์ .htaccess ไม่ได้ และแสดงโค้ดให้คัดลอกเอง แปลว่าสิทธิ์ไฟล์ไม่อนุญาต ให้ไปขั้นตอนที่ 3 ส่วนผู้ที่ใช้ WP-CLI ทำแบบเดียวกันได้ด้วยคำสั่ง
wp rewrite structure '/%postname%/'
wp rewrite flush --hard
ตัวเลือก --hard สั่งให้เขียนไฟล์ .htaccess ด้วย (มีผลเฉพาะบน Apache) ดูการใช้ WP-CLI เพิ่มเติมได้ที่ จัดการ WordPress ด้วย WP-CLI
ขั้นตอนที่ 3: ตรวจไฟล์ .htaccess (Apache และ LiteSpeed)
เปิดไฟล์ .htaccess ที่อยู่ในโฟลเดอร์เดียวกับ wp-config.php (เช่น httpdocs บน Plesk หรือ public_html บน DirectAdmin) ไฟล์นี้ขึ้นต้นด้วยจุด บาง File Manager จะซ่อนไว้ ต้องเปิดตัวเลือกแสดงไฟล์ซ่อนก่อน เนื้อหามาตรฐานของ WordPress คือ
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
ถ้าไฟล์ไม่มีบล็อกนี้ ให้เพิ่มเข้าไป ถ้าติดตั้ง WordPress ไว้ในโฟลเดอร์ย่อย เช่น https://example.com/blog/ ให้แก้สองบรรทัดเป็น RewriteBase /blog/ และ RewriteRule . /blog/index.php [L]
ตรวจสิทธิ์ไฟล์ให้ WordPress เขียนได้ในครั้งต่อไป โดยปกติ 644 ก็เพียงพอ หากเจ้าของไฟล์ตรงกับผู้ใช้ที่ PHP ทำงานอยู่
ls -l /var/www/example.com/.htaccess
chmod 644 /var/www/example.com/.htaccess
รายละเอียดเรื่องสิทธิ์ไฟล์อ่านต่อได้ที่ ทำความเข้าใจสิทธิ์ไฟล์บน Linux ด้วย chmod และ chown
ขั้นตอนที่ 4: เปิด mod_rewrite และ AllowOverride (Cloud Server ที่ใช้ Apache)
ถ้า .htaccess ถูกต้องแล้วแต่ยังเป็น 404 มักเป็นเพราะ Apache ไม่อ่านไฟล์นี้เลย ค่าเริ่มต้นของทั้ง Ubuntu และ AlmaLinux/Rocky ตั้ง AllowOverride None ไว้
Ubuntu 22.04 / 24.04
sudo a2enmod rewrite
จากนั้นแก้ไฟล์ Virtual Host ของเว็บ เช่น /etc/apache2/sites-available/example.com.conf ให้มีบล็อกนี้อยู่ภายใน <VirtualHost>
<Directory /var/www/example.com>
AllowOverride All
Require all granted
</Directory>
sudo apache2ctl configtest
sudo systemctl reload apache2
คำสั่ง configtest ต้องตอบว่า Syntax OK ก่อนจึง reload
AlmaLinux / Rocky Linux 8-9
mod_rewrite ถูกโหลดไว้แล้วโดยค่าเริ่มต้น ตรวจได้ด้วย
httpd -M | grep rewrite
ควรเห็น rewrite_module (shared) จากนั้นเพิ่มบล็อก <Directory> แบบเดียวกันในไฟล์ใต้ /etc/httpd/conf.d/ หรือแก้บล็อก <Directory "/var/www/html"> ใน /etc/httpd/conf/httpd.conf ให้เป็น AllowOverride All แล้ว
sudo apachectl configtest
sudo systemctl reload httpd