ไฟล์ .htaccess (Hypertext Access) คือไฟล์ configuration ขนาดเล็กที่ Apache Web Server อ่านแบบ per-directory — ทุกครั้งที่มี HTTP request เข้ามา Apache จะตรวจสอบ .htaccess ใน directory นั้นพร้อมกับทุก parent directory ตลอดเส้นทาง ทำให้เจ้าของเว็บไซต์สามารถปรับแต่งพฤติกรรม server ได้โดยไม่ต้องมีสิทธิ์แก้ httpd.conf หลัก

ใน Shared Hosting และ DirectAdmin Hosting .htaccess จึงเป็นเครื่องมือหลักที่นักพัฒนาเว็บและผู้ดูแลระบบใช้ทำ URL Redirect, บังคับ HTTPS, ตั้ง Browser Cache, เปิด GZIP Compression, เพิ่ม Security Headers และแก้ปัญหาด้านประสิทธิภาพต่างๆ บทความนี้รวม .htaccess Commands ที่ใช้บ่อยที่สุดในโลกจริงสำหรับ WordPress และ PHP Web Application พร้อมคำอธิบายและตัวอย่างที่ทดสอบแล้วบน Apache 2.4

พื้นฐาน .htaccess ก่อนเริ่มใช้งาน

ก่อนเพิ่ม directive ใดๆ ลงใน .htaccess ควรทำความเข้าใจหลักการทำงานพื้นฐาน 3 ข้อ:

บรรทัดที่ขึ้นต้นด้วย # คือ comment ไม่มีผลต่อการทำงาน ควรใส่ comment ไว้เสมอเพื่อให้ทราบว่า block นั้นทำอะไร โดยเฉพาะเมื่อมีหลาย rule รวมกัน

WordPress Permalink — .htaccess มาตรฐาน

WordPress ใช้ mod_rewrite เพื่อ route ทุก request ที่ไม่ตรงกับไฟล์หรือ directory จริงไปยัง index.php ซึ่งเป็นกลไกหลักของ WordPress Routing System block นี้ WordPress Dashboard จะเขียนให้อัตโนมัติเมื่อตั้งค่า Permalinks แต่ควรรู้ว่าแต่ละบรรทัดทำอะไร:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

คำอธิบายแต่ละบรรทัด: RewriteBase / กำหนด base path สำหรับ relative rule — ถ้า WordPress อยู่ใน subdirectory เช่น /blog/ ต้องเปลี่ยนเป็น RewriteBase /blog/ และแก้ RewriteRule . /blog/index.php [L] ด้วย RewriteCond %{REQUEST_FILENAME} !-f และ !-d หมายถึง "ถ้าไม่ใช่ไฟล์จริงและไม่ใช่ directory จริง ค่อย route ไป index.php" ทำให้ไฟล์ static เช่น .jpg, .css, .js ยังเสิร์ฟได้ปกติ

ถ้า WordPress อยู่ใน subdirectory เช่น https://example.com/wp/ ต้องเปลี่ยน block ให้ตรงกับ path จริง:

# BEGIN WordPress (installed in /wp/)
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /wp/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /wp/index.php [L]
</IfModule>
# END WordPress

GZIP Compression — ลดขนาดไฟล์ถ่ายโอน

GZIP Compression ช่วยลดขนาดไฟล์ HTML, CSS, JavaScript และ XML ก่อนส่งจาก server ไปยัง browser ได้ถึง 60-80% ทำให้หน้าโหลดเร็วขึ้นมากโดยเฉพาะบนการเชื่อมต่อที่ช้า บน Apache ใช้ mod_deflate:

<IfModule mod_deflate.c>
  # บีบอัด text-based content
  AddOutputFilterByType DEFLATE text/plain
  AddOutputFilterByType DEFLATE text/html
  AddOutputFilterByType DEFLATE text/xml
  AddOutputFilterByType DEFLATE text/css
  AddOutputFilterByType DEFLATE application/xml
  AddOutputFilterByType DEFLATE application/xhtml+xml
  AddOutputFilterByType DEFLATE application/rss+xml
  AddOutputFilterByType DEFLATE application/javascript
  AddOutputFilterByType DEFLATE application/x-javascript
  AddOutputFilterByType DEFLATE application/json

  # ไม่บีบอัดไฟล์ที่บีบแล้ว
  SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|webp|svg|ico|zip|gz|bz2|mp4|mp3)$ no-gzip dont-vary
</IfModule>

ตรวจสอบว่า GZIP ทำงานหรือยังด้วยคำสั่ง: curl -H "Accept-Encoding: gzip" -I https://example.com/ ถ้า response header มี Content-Encoding: gzip แสดงว่าเปิดใช้งานแล้ว

Browser Caching — ลด Request ซ้ำ

Browser Caching กำหนดให้ browser เก็บ static files เช่น รูปภาพ CSS JS ไว้ใน cache เพื่อไม่ต้อง download ซ้ำในการเยี่ยมชมครั้งถัดไป ช่วยลด bandwidth และเพิ่มความเร็วโหลดหน้าอย่างมีนัยสำคัญ ใช้ mod_expires:

<IfModule mod_expires.c>
  ExpiresActive On
  ExpiresDefault "access plus 1 month"

  # รูปภาพ — cache 1 ปี
  ExpiresByType image/jpeg "access plus 1 year"
  ExpiresByType image/png "access plus 1 year"
  ExpiresByType image/gif "access plus 1 year"
  ExpiresByType image/webp "access plus 1 year"
  ExpiresByType image/svg+xml "access plus 1 year"
  ExpiresByType image/x-icon "access plus 1 year"

  # CSS และ JavaScript — cache 1 เดือน
  ExpiresByType text/css "access plus 1 month"
  ExpiresByType application/javascript "access plus 1 month"
  ExpiresByType application/x-javascript "access plus 1 month"

  # Font files — cache 1 ปี
  ExpiresByType font/woff2 "access plus 1 year"
  ExpiresByType font/woff "access plus 1 year"
  ExpiresByType application/font-woff2 "access plus 1 year"

  # HTML และ XML — cache สั้น
  ExpiresByType text/html "access plus 1 hour"
  ExpiresByType application/xml "access plus 0 seconds"
  ExpiresByType application/rss+xml "access plus 1 hour"
</IfModule>

<IfModule mod_headers.c>
  Header append Cache-Control "public"
</IfModule>

Tip สำคัญ: ถ้าอัพเดต CSS หรือ JS แล้วผู้ใช้ยังเห็นเวอร์ชันเก่าเนื่องจาก cache ให้ใช้ Cache Busting — เพิ่ม query string ต่อท้าย URL เช่น style.css?v=20260609 browser จะมองว่าเป็นไฟล์ใหม่และ download ใหม่โดยไม่ต้องรอ cache หมดอายุ

Security Headers และการป้องกัน WordPress

Security Headers ช่วยป้องกันช่องโหว่ด้านความปลอดภัยหลายประเภทโดยไม่ต้องแก้ code ใน application เลย เหมาะมากสำหรับ WordPress ที่มักตกเป็นเป้าหมายของการโจมตี:

<IfModule mod_headers.c>
  # ป้องกัน Clickjacking
  Header always set X-Frame-Options "SAMEORIGIN"

  # ป้องกัน MIME Type Sniffing
  Header always set X-Content-Type-Options "nosniff"

  # XSS Protection (legacy browsers)
  Header always set X-XSS-Protection "1; mode=block"

  # Referrer Policy
  Header always set Referrer-Policy "strict-origin-when-cross-origin"

  # บังคับ HTTPS (HSTS) — ตั้งค่าหลังมั่นใจว่า HTTPS ทำงานปกติ
  Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
</IfModule>

บล็อก xmlrpc.php (WordPress)

xmlrpc.php เป็นไฟล์ที่ WordPress ใช้สำหรับ remote publishing และ Jetpack แต่มักถูกใช้เป็นช่องโจมตีแบบ Brute Force และ DDoS ถ้าไม่ได้ใช้ควรบล็อกทิ้ง:

# บล็อก xmlrpc.php
<Files xmlrpc.php>
  Order Deny,Allow
  Deny from all
</Files>

บล็อก PHP ใน /uploads/ (WordPress)

ไดเรกทอรี uploads/ ไม่ควรสามารถ execute PHP file ได้ เพราะถ้า attacker อัพโหลด PHP ไฟล์ปลอมปน image ได้จะสามารถรันคำสั่งบน server ได้ ให้สร้าง .htaccess แยกใน wp-content/uploads/.htaccess:

# ป้องกัน PHP execution ใน uploads/
<FilesMatch "\.php$">
  Order Allow,Deny
  Deny from all
</FilesMatch>

การตั้งค่า PHP ผ่าน .htaccess

บน Shared Hosting ที่ไม่มีสิทธิ์แก้ php.ini โดยตรง สามารถ override ค่า PHP บางตัวผ่าน .htaccess ได้ ขึ้นอยู่กับว่า Hosting อนุญาตหรือไม่ (DirectAdmin Hosting ของ AsiaGB รองรับ):

# เพิ่ม PHP memory limit
php_value memory_limit 256M

# เพิ่ม max upload file size
php_value upload_max_filesize 64M
php_value post_max_size 64M

# เพิ่ม max execution time (วินาที)
php_value max_execution_time 300

# ซ่อน PHP error ในหน้าเว็บ (production)
php_flag display_errors Off

# เปิด error logging (log ไปยัง error_log แทน)
php_flag log_errors On

# ตั้ง timezone
php_value date.timezone "Asia/Bangkok"

# ป้องกัน session hijacking
php_value session.cookie_httponly 1
php_value session.cookie_secure 1

ถ้าใส่ php_value แล้วเกิด 500 Error แสดงว่า Hosting นั้นไม่อนุญาต PHP override ผ่าน .htaccess ให้ลองใช้ไฟล์ php.ini หรือ user.ini ใน root directory แทน

Custom Error Pages

การตั้ง Custom Error Pages ทำให้ผู้ใช้เห็นหน้า error ที่สวยงามและมี navigation กลับสู่เว็บแทนหน้า error มาตรฐานของ server ซึ่งดูไม่เป็นมิตรและอาจเปิดเผยข้อมูล server:

# Custom Error Pages
ErrorDocument 400 /error/400.html
ErrorDocument 401 /error/401.html
ErrorDocument 403 /error/403.html
ErrorDocument 404 /error/404.html
ErrorDocument 500 /error/500.html

สำหรับ WordPress ให้ใช้หน้า 404 ของ WordPress แทน เพราะ WordPress มีระบบ routing ของตัวเอง การ override ErrorDocument 404 นอก WordPress block อาจทำให้ WordPress 404 handler ไม่ทำงาน

ป้องกัน Hotlinking และจำกัดการเข้าถึง

Hotlinking คือการที่เว็บอื่นโหลดรูปภาพจากเซิร์ฟเวอร์ของคุณโดยตรง ทำให้ bandwidth หมดโดยไม่ได้ประโยชน์ ป้องกันได้ด้วย mod_rewrite:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?yourdomain\.com [NC]
RewriteRule \.(jpg|jpeg|png|gif|webp|svg)$ - [F,NC]
</IfModule>

บรรทัดที่ 2 อนุญาตให้เข้าถึงได้ถ้า Referer ว่างเปล่า (เช่น พิมพ์ URL โดยตรงหรือ curl) บรรทัดที่ 3 อนุญาตเฉพาะ request จากโดเมนของคุณเอง flag [F] ส่ง 403 Forbidden แทนที่จะ serve ไฟล์

บล็อก User-Agent ที่ไม่พึงประสงค์

<IfModule mod_rewrite.c>
RewriteEngine On
# บล็อก bot/scanner ที่รู้จัก
RewriteCond %{HTTP_USER_AGENT} (nikto|sqlmap|netsparker|acunetix|dirbuster) [NC]
RewriteRule .* - [F,L]
</IfModule>

ตารางสรุป .htaccess Commands ที่ใช้บ่อยที่สุด

ตารางนี้รวมคำสั่งสำคัญพร้อมวัตถุประสงค์และ module ที่ต้องการ ใช้เป็น quick reference เมื่อต้องการค้นหาคำสั่งที่ใช่:

Category คำสั่ง / Directive Module วัตถุประสงค์
Redirect Redirect 301 mod_alias ย้าย URL ถาวร รักษา SEO
Rewrite RewriteRule / RewriteCond mod_rewrite เปลี่ยน URL pattern, WordPress routing
GZIP AddOutputFilterByType DEFLATE mod_deflate บีบอัดไฟล์ก่อนส่ง ลด bandwidth
Cache ExpiresByType mod_expires กำหนดอายุ browser cache
Headers Header always set mod_headers Security headers, CORS, HSTS
PHP php_value / php_flag mod_php Override php.ini สำหรับ directory นั้น
Access Order Deny,Allow / <Files> mod_access จำกัดการเข้าถึงไฟล์หรือ IP
Error ErrorDocument core กำหนดหน้า error ที่กำหนดเอง

Best Practices และข้อควรระวัง

การใช้ .htaccess อย่างถูกต้องจะช่วยให้เว็บทำงานได้ดีขึ้น แต่ถ้าตั้งค่าผิดอาจทำให้เว็บล่มได้ทันที ควรปฏิบัติตามแนวทางต่อไปนี้เสมอ:

คำถามที่พบบ่อย (FAQ)

.htaccess ใช้กับ Hosting ทุกประเภทได้ไหม

.htaccess ใช้ได้เฉพาะ Hosting ที่ใช้ Apache Web Server เท่านั้น ซึ่งครอบคลุม Shared Hosting และ VPS ส่วนใหญ่รวมถึง DirectAdmin Hosting ของ AsiaGB หาก Hosting ใช้ Nginx จะต้องใส่ directive ใน nginx.conf แทน และถ้าใช้ LiteSpeed Server จะรองรับ .htaccess เหมือน Apache เกือบทั้งหมด

แก้ .htaccess แล้วเว็บขึ้น 500 Internal Server Error ต้องทำอย่างไร

500 Error จาก .htaccess มักเกิดจาก syntax ผิด เช่น directive สะกดผิด, flag ขาดวงเล็บ [L] หรือ mod_rewrite ยังไม่ได้เปิด ให้ตรวจ Error Log ใน DirectAdmin (Logs > Error Log) เพื่อดู error message จริง หรือใช้คำสั่ง curl -I เพื่อดู HTTP status และ header response ก่อนแก้ไข และควร Backup .htaccess เดิมไว้ก่อนทุกครั้ง

WordPress ต้องการ .htaccess แบบพิเศษอะไรบ้าง

WordPress ต้องการ RewriteRule สำหรับ Permalink ซึ่ง WordPress Dashboard (Settings > Permalinks) จะสร้าง .htaccess block ให้อัตโนมัติ นอกจากนี้ยังนิยมเพิ่ม GZIP Compression เพื่อลดขนาดไฟล์, Browser Caching เพื่อเพิ่มความเร็ว, บล็อก xmlrpc.php เพื่อป้องกัน brute force และบล็อก .php execution ใน /uploads/ เพื่อป้องกัน malware upload

ไฟล์ .htaccess หลายไฟล์ใน subdirectory ต่างกันอย่างไรจาก root

Apache ประมวลผล .htaccess ตั้งแต่ root ลงมาถึง directory ของ request นั้น ทุก .htaccess ในเส้นทางจะถูกรวมกัน โดยไฟล์ที่อยู่ลึกกว่าจะ override ไฟล์บน สำหรับ WordPress ควรให้ root .htaccess จัดการ RewriteRule ส่วน subdirectory เช่น /uploads/ มี .htaccess แยกเพื่อบล็อก PHP execution เท่านั้น การแยกไฟล์แบบนี้ช่วยให้ดูแลรักษาง่ายกว่าใส่ทุกอย่างในที่เดียว

Hosting DirectAdmin ครบชุดของ AsiaGB

AsiaGB Hosting รองรับ DirectAdmin เต็มรูปแบบ PHP 8.3 MySQL เริ่มต้น 500 บาท/ปี

ดูแพ็กเกจ Hosting