Mod_Rewrite ภาษาไทย วิธีทำ Mod_Rewrite URL Mod_Rewrite คืออะไร

Mod_Rewrite ภาษาไทย วิธีทำ Mod_Rewrite URL Mod_Rewrite คืออะไร

ตอนนี้มีเว็บไซด์หลายเว็บที่มี URL เป็นภาษาไทย หรือ เป็นคำที่อ่านง่ายกว่าเมื่อก่อนอย่างเห็นได้ชัด เนื่องจาก dynamic URL นั้น นอกจากจะทำให้ไม่รู้เรื่องจำยากแล้ว บรรดา Search Engine ก็ยังไม่ชอบอีกด้วย เพราะฉะนั้นจะช้าอยู่ทำไมมาแก้เว็บแปลงจาก dynamic URL ให้กลายเป็นเพจที่อ่านง่ายๆ จำง่ายๆ และ ดีต่อ SEO กันดีกว่าครับ

Mod_Rewrite คืออะไร?

Mod_Rewrite คือการแปลง URL ที่ดูยากให้อยู่ในรูปแบบที่เราต้องการ เพื่อประโยชน์หลายด้าน (ซึ่งจะกล่าวถึงต่อไป) และการแปลงเพื่อประโยชน์ด้าน SEO ก็เป็นอีกอันนึงที่มีการนำเอา Mod_Rewrite มาใช้ เพราะเรารู้กันดีว่า Search Engine ไม่ค่อยชอบ pages ที่เป็น dynamic ที่มี query string ยาวๆๆๆ

บทควาามที่แล้วผมได้แสดงตัวอย่าง dynamic ที่ยาวๆ อันนี้ขึ้นมา

http://www.yousite com/product.php?page_id=41
ว่าให้เปลี่ยนเป็นแบบนี้
http://www.yousite.com/product/shoes/

เริ่มทำ Mod_Rewrite

บาง Server ไม่สามารถจะทำ Mod_Rewrite ได้เนื่องจากไม่ได้ติดตั้ง Module Mod_Rewrite ดังนั้นถ้าเราจำเป็นต้องใช้ Mod_Rewrite ก็ต้องตรวจสอบดีๆก่อนเช่า host

.htaccess ไฟล์สำคัญในการทำ Mod_Rewrite

ไม่รู้ว่ามีใครเป็นเหมือนกับผมมั้ยนะครับเพราะตอนแรกที่ผมจะทำ Mod_Rewrite รุ่นพี่บอกว่าให้ทำไฟล์ .htaccess ขึ้นมาก็นั่ง งง อยู่ว่ามันจะอะไร 555+ เพราะเห็นมันเป็นดอทเลยนึกว่าเป็นสกุลไฟล์ สรุปง่ายๆ คือไม่ต้องคิดว่าจะชื่ออะไร หรือ นามสกุลอะไรหรอกครับ เปิด Notepad หรือถ้าใครใช้ dreamweaver ก็เปิดหน้าใหม่ขึ้นใหม่จะเลือก HTML หรือ PHP หรืออะไรก็ได้ครับ ตอน save ก็ save ว่า .htaccess ได้เลย เตรียมไฟล์เปล่าๆ ขึ้นมาได้เลยครับ เราจะเริ่มทำ .htaccess ในการกำหนด Rule ของการทำ Mod_Rewrite พร้อมๆ กัน นะครับ

เริ่มต้นด้วยคำสั่ง RewriteEngine on


เพื่อเปิดการทำงาน เขียนไว้ในบรรทัดแรกสุดของไฟล์ ต่อไปจะเป็นการนำเอา Mod_Rewrite ไปให้งานซึ่งผมจะเริ่มด้วยตัวอย่างง่ายๆ และเขียน Rewrite Rule ง่ายก่อน แล้วก็ยกตัวอย่างต่อไปเรื่อยๆนะครับ

ใช้ Mod_Rewrite ในการทำ Redirects

ถ้าเราต้องการเปลี่ยน location เก่า ไปที่ Location ใหม่แบบถาวร

RewriteEngine on
RewriteRule ^old\.html$ new.html

ถ้าเราเขียนแบบนี้ เมื่อมีการใส่ url เป็น old.html มันก็จะถูกส่งไปที่ไพล์ new.html แต่ผู้เยี่ยมชมยังเห็น URL บน browser เป็น old.html อยู่เหมือนเดิม

อาจจะดูงงๆ อธิบายเพิ่มเติมดังนี้ RewriteRule จะประกอบด้วยกัน 3 ส่วน
1. Call to action RewriteRule ขึ้นต้นบรรทัด กำหนดว่าบรรทัดนี้เป็น Rewrite Rule
2. Pattern ^old\.html$ เป็นการตรวจสอบ URL ที่ใส่เข้ามาทาง Location Bar ของ Browser ซึ่งจะใช้ regex (Regular Expression) ในการตรวจสอบ (จะอธิบายเพิ่มเติมต่อไป)
3. Rewrite new.html เป็น URL ที่เราต้องการให้แปลงเป็นอันใหม่
หมายเหตุ: จริงๆมี 4 ส่วน แต่ในตัวอย่างเราใช้ 3 ส่วน

ขออธิบายในส่วนที่ 2 (Pattern) เพิ่มเติมดังนี้ ในส่วนนี้ประกอบด้วยเครื่องหมายสำคัญ 3 อย่างคือ
^old\.html$
- เครื่องหมาย The caret หรือ ^ เป็นการกำหนดจุดเริ่มต้น URL ที่อยู่ภายใต้ direcory ปัจจุบันที่เราจะตรวจสอบ ซึ่งก็คือ directory เดียวกับไฟล์ .htaccess
- เครื่องหมาย The dollar sign หรือ $ ซึ่งบอกจุดสิ้นสุดของการตรวจสอบ Pattern
- อีกเครื่องหมายนึงก็คือ The period หรือ . จุด ที่อยู่ข้างหน้านามสกุล html ซึ่งเครื่องหมาย จุด นั้นเป็นอักขระพิเศษ ใน regular expressions ซึ่งจะมีความหมายว่า แทนด้วยตัวอักษรใดๆ 1 ตัว (ดูเพิ่มเติมใน regular expressions ต่อจากนี้) แต่ในนี้เราจะตรวจสอบว่า ถ้า Pattern เป็น old.html หรือไม่ เราจึงต้องใส่ \ ซึ่งเป็น escape charactor ไว้ด้วย

เมื่อเราเขียนตามนี้ เมื่อผู้เยี่ยมชมเว็บกรอกมาเป็น old.html server ก็จะทำ transparently redirect ไปที่ new.html โดยที่ผู้เยี่ยมชมเว็บไม่รู้ตัวว่าเป็นข้อมูลอันใหม่แล้ว เพราะ URL บน browser เป็น old.html อยู่เหมือนเดิม

แต่ถ้าเราต้องการให้ URL ที่ปรากฏบน browser เป็น new.html ด้วย เราก็เพียงแต่เติม [R] เข้าไปต่อท้ายบรรทัด ดังนี้

RewriteRule ^old\.html$ new.html [R]

ซึ่ง [R] ก็คือ ส่วนที่ 4 ที่ผมบอกไว้ข้างบน
4. Command Flag [R] ซึ่งจะเป็นคำสั่งพิเศษกำหนดเงื่อนไขไว้ มีหลายคำสั่งซึ่งจะบอกไว้ตอนท้าย

การใช้ Regular Expressions

จะบอกว่า เป็นส่วนสำคัญที่สุดในการทำ Rewrite และมันก็ทำความความเข้าใจได้ยากพอควร ไม่ต้องห่วงครับ เดี๋ยวผมจะอธิบายเป็นขั้นตอน และยกตัวอย่างประกอบไปเรื่อยๆนะครับ


ตัวอย่างแรก


RewriteRule ^products/([0-9][0-9])/$ productinfo.php?prodID=$1

จะเปลี่ยนจาก

productinfo.php?prodID=11 หรือ productinfo.php?prodID=99

ให้เป็น

products/11/ หรือ products/99/

ดูที่ Pattern จะมีส่วนของที่อยู่ในปีกกาเหลี่ยม [ ] เราเรียกว่า ranges ในตัวอย่างจะเป็น [0-9] ซึ่งจะใช้ตรวจสอบว่าเป็นตัวอักษรที่อยู่ในช่วง 0-9 ใดๆ เราสามารถตรวจสอบ ranges อื่นได้ เช่น [A-Z] ตรวจสอบว่าเป็นตัวอักษรตัวใหญ่ตั้งแต่ A-Z [a-z] ก็เป็นการตรวสอบตัวเล็ก, ถ้า [A-Za-z] ก็ตรวจสอบว่าเป็นทั้งตัวใหญ่และตัวเล็ก เป็นต้น และใน Pattern ก็จะมีส่วนที่อยู่ในวงเล็บ ( ) เป็นการเก็บค่าที่เราตรวจสอบพบ และตรงตามเงื่อนไข ซึ่งเราสามารถเอาค่านี้ ส่งไปให้ PHP ในส่วนของ Query String ได้ เราเรียกค่าที่ได้จากวงเล็บนี่ว่า back-reference
เราสามารถตรวจสอบและแยก back-reference ออกได้หลายๆอันใน URL อันเดียว (ดูตัวอย่างต่อๆไป) ซึ่งback-reference ในวงเล็บแรก เวลาเราอ้างถึงเราก็จะใช้ $1 ส่วนลำดับต่อๆไป ก็จะเป็น $2, $3 ไปเรื่อยๆดังนั้นผู้เยี่ยมชมเว็บ(หรือ bot ก็ได้)ก็จะเห็น url เป็น products/11/ หรือ products/99/ ซึ่ง สั้นและกระชับ โดยหารู้ไม่ว่า เราได้ซ่อน URL ที่ไม่ค่อยสวยงามและอ่านยากไว้เบื้องหลัง


ใส่ / ต่อท้าย

บางครั้งผู้เยี่ยมชมเว็บ อาจจะพิมพ์ URL แค่ products/12 ซึ่งเมื่อเข้าไปตรวจสอบใน Pattern ด้านบน ก็จะไม่ตรง เพราะ Pattern ด้านบนจะต้องมี / ต่อท้ายด้วย มันจึงไม่ทำ transparently redirect ให้เรา
เราก็มีวิธีแก้เหตุการณ์แบบนี้ ซึ่งเราก็จะเขียน Rule ใหม่เพิ่มเข้าไปดังนี้


RewriteRule ^products/([0-9][0-9])$ products/$1/ [R]
RewriteRule ^products/([0-9][0-9])/$ productinfo.php?prodID=$1

ดังนั้น เมื่อ Server ตรวจเจอ products/12 ก็จะเปลี่ยน URL เป็น products/12/ และแสดง URL ให้บน Browser ด้วย เพราะเราใส่ [R] ไว้ด้วย เมื่อเจอเงื่อนไขบรรทัดที่ 2 ก็เลยไม่มีปัญหาใดๆ ซึ่งมันก็จะส่งเป็น transparently redirect ไปที่ productinfo.php?prodID=12 ตามความต้องการของเรา

การใช้ Match Quantifiers

จะเป็นว่าตัวอย่างข้างบน เรากำหนดเป็น ^products/([0-9][0-9])$ นั่นหมายความว่า ตัวเลขที่ตามหลัง products/xx ต้องมี 2 ตัวเท่านั้น ซึ่งก็จะเป็นไปได้สูงสุดแค่ 99 แล้วกรณี productinfo.php?prodID=100 ล่ะจะทำอย่างไร?
ในกรณีนี้ เราสามารถใช้ Quantifiers เป็นตัวกำหนดได้ (Quantifiers มีหลายตัว จะอธิบายต่อไปเรื่อยๆ) ดังตัวอย่าง

RewriteRule ^products/([0-9]+)$ products/$1/ [R]
เครื่องหมายบวก + แทนอักษรตั้งแต่ 1 ตัว ถึง n ตัว (ตั้งแต่ 1 ตัวขึ้นไป) ดังนั้น [0-9]+ ก็หมายความว่า เป็นตัวเลข 0-9 ตั้งแต่ 1 หลักขึ้นไป ถ้าเราใส่ products/1 หรือ products/1000 ก็สามารถ Match case นี้ได้แล้วครับ

มาว่ากันต่อเรื่องเดิมนะครับว่าจะทำอย่างไรให้

http://www.yousite com/product.php?page_id=41
กลายเป็น

http://www.yousite.com/product/shoes/

จะเขียนแบบไหนดี จริงๆ แตละคนอาจมีวิธีคิด และ เขียนที่แตกต่างกันไป หลังจากอ่านบทความแล้วก็สามารถไปต่อยอดกันเองได้นะครับแต่ผม
ขอยกตัวอย่างการเขียนแบบง่ายๆ ก่อนนะครับ ผมจะเขียนลักษณะนี่้ครับ

RewriteEngine On
RewriteRule ^product/([^/]*)\.html$ \ com/product.php?page_id=$1

วิธีการเขียนของผมก็คือใช้วิธีสร้าง ชื่อ โฟลเดอร์ ปลอมๆ ใส่เข้าไปเลยคือ product/ และการ \.html คือการทำให้นามสกุลไฟล์ที่เรามองเห็นเป็น
.html และชื่อหน้าที่จะเกิดขึ้นนั้นคือ 41 เราก็จะได้ URL ใหม่เป็นชื่อนี้ครับ
http://www.yousite.com/product/41.html

จากนั้นให้เพิ่ม field ไปในดาต้าเบส 1 field สมมุติว่าชื่อ page_name แล้วใน field นี้เราก็ใส่ชื่อที่ต้องการเข้าไปเช่น shoes, watch หรือ
อะไรก็ได้ครับ จากนั้นเปลี่ยนที่ .htaccess เป็น

RewriteEngine On
RewriteRule ^product/([^/]*)]*)/$ \com/com/product.php?page_name=$1

ก็จะได้ URL ใหม่เป็นชื่อนี้ครับ

http://www.yousite.com/product/shoes.html

ขั้นตอนต่อไปให้เราแก้ .htaccess ให้เป็นลักษณะของ โฟลเดอร์ซึ่งก็ไม่ยากเลยครับแค่

RewriteEngine On
RewriteRule ^product/([^/]*)\.html$ \ com/product.php?page_name=$1

เราก็จะได้

http://www.yousite.com/product/shoes/

เห็นมั้ยครับไม่ยากเลยแล้วใครอยากให้มันเป็นภาษาไทยก็แค่ใส่ข้อมูลใน page_name แค่นั้นเองครับ