RewriteBaseใช้กับเป้าหมายของกฎการเขียนซ้ำแบบสัมพันธ์เท่านั้น
ใช้ RewriteBase เช่นนี้ ...
RewriteBase /folder/
RewriteRule a\.html b.html
โดยพื้นฐานแล้วเหมือนกับ ...
RewriteRule a\.html /folder/b.html
แต่เมื่อไฟล์. htaccess อยู่ด้านใน/folder/นี่จะชี้ไปยังเป้าหมายเดียวกัน:
RewriteRule a\.html b.html
แม้ว่าเอกสารจะหมายถึงการใช้เสมอRewriteBaseแต่ Apache มักตรวจพบอย่างถูกต้องสำหรับเส้นทางภายใต้ DocumentRoot เว้นแต่:
ในกรณีเหล่านี้คุณอาจพบว่าคุณต้องระบุ RewriteBase
อย่างไรก็ตามเนื่องจากเป็นคำสั่งที่สับสนคุณควรระบุ URIs แบบสัมบูรณ์ (หรือที่เรียกว่า 'รูทญาติ') ในเป้าหมายที่เขียนซ้ำของคุณ นักพัฒนาอื่น ๆ ที่อ่านกฎของคุณจะเข้าใจสิ่งเหล่านี้ได้ง่ายขึ้น
อ้างจากคำตอบเชิงลึกที่ยอดเยี่ยมของจอนหลินที่นี่ :
ในไฟล์ htaccess mod_rewrite จะทำงานคล้ายกับ<Directory>หรือ<Location>คอนเทนเนอร์ และRewriteBaseใช้เพื่อจัดทำฐานพา ธ สัมพัทธ์
ตัวอย่างเช่นสมมติว่าคุณมีโครงสร้างโฟลเดอร์นี้:
DocumentRoot
|-- subdir1
`-- subdir2
`-- subsubdir
ดังนั้นคุณสามารถเข้าถึง:
http://example.com/ (ราก)
http://example.com/subdir1 (subdir1)
http://example.com/subdir2 (subdir2)
http://example.com/subdir2/subsubdir (subsubdir)
URI ที่ส่งผ่าน a RewriteRuleนั้นสัมพันธ์กับไดเรกทอรีที่มีไฟล์ htaccess ดังนั้นถ้าคุณมี:
RewriteRule ^(.*)$ -
- ใน htaccess รากและขอเป็น
/a/b/c/dแล้วจับ URI ( $1) a/b/c/dเป็น
- หากกฎอยู่ใน
subdir2และคำขอ/subdir2/e/f/gนั้นจะเป็น URI ที่จับe/f/gได้
- หากการปกครองที่อยู่ใน
subsubdirและขอเป็น/subdir2/subsubdir/x/y/zแล้วจับ URI x/y/zคือ
ไดเรกทอรีที่กฎนั้นมีอยู่นั้นส่วนนั้นถูกแยกออกจาก URI การเขียนซ้ำไม่มีผลกับสิ่งนี้นี่เป็นเพียงการทำงานของแต่ละไดเรกทอรี
สิ่งที่ฐานเขียนไม่ทำคือให้ฐาน URL เส้นทาง ( ไม่ฐานไฟล์เส้นทาง) สำหรับเส้นทางญาติใด ๆ ในเป้าหมายของกฎ สมมติว่าคุณมีกฎนี้:
RewriteRule ^foo$ bar.php [L]
bar.phpเป็นเส้นทางญาติเมื่อเทียบกับ:
RewriteRule ^foo$ /bar.php [L]
โดยที่/bar.phpเป็นเส้นทางที่แน่นอน เส้นทางแน่นอนจะเสมอเป็น "ราก" (ในโครงสร้างไดเรกทอรีข้างต้น) นั่นหมายความว่าไม่ว่ากฎนั้นจะอยู่ใน "root", "subdir1", "subsubdir" ฯลฯ/bar.phpเส้นทางจะจับคู่กับhttp://example.com/bar.phpเสมอ
แต่กฎอื่น ๆ ที่มีเส้นทางสัมพัทธ์มันขึ้นอยู่กับไดเรกทอรีที่กฎอยู่ค่ะดังนั้นถ้า
RewriteRule ^foo$ bar.php [L]
อยู่ใน "ราก" และคุณไปที่คุณได้รับบริการhttp://example.com/foo http://example.com/bar.phpแต่ถ้ากฎที่อยู่ใน "subdir1 directory" และคุณไปที่คุณได้รับบริการhttp://example.com/subdir1/foo http://example.com/subdir1/bar.phpฯลฯ บางครั้งวิธีนี้ใช้งานได้และบางครั้งไม่เป็นไปตามที่เอกสารระบุว่าควรใช้เส้นทางที่สัมพันธ์กัน แต่ส่วนใหญ่แล้วดูเหมือนว่าจะใช้งานได้ ยกเว้นเมื่อคุณเปลี่ยนเส้นทาง (ใช้การRตั้งค่าสถานะหรือโดยปริยายเพราะคุณhttp://hostอยู่ในเป้าหมายของกฎ) นั่นหมายถึงกฎนี้:
RewriteRule ^foo$ bar.php [L,R]
ถ้ามันใน "subdir2 directory" และคุณจะไปhttp://example.com/subdir2/foo, mod_rewrite จะผิดพลาดทางญาติเป็นไฟล์เส้นทางแทน URL เส้นทางและเนื่องจากธงคุณจะจบลงได้รับการเปลี่ยนเส้นทางไปยังสิ่งที่ต้องการ:R http://example.com/var/www/localhost/htdocs/subdir1ซึ่งเห็นได้ชัดว่าไม่ใช่สิ่งที่คุณต้องการ
นี่คือที่RewriteBaseมาคำสั่งบอก mod_rewrite สิ่งที่จะผนวกกับจุดเริ่มต้นของทุกเส้นทางญาติ ดังนั้นถ้าฉันมี:
RewriteBase /blah/
RewriteRule ^foo$ bar.php [L]
ใน "subsubdir" จะไปhttp://example.com/subdir2/subsubdir/fooรับใช้ฉันจริงhttp://example.com/blah/bar.phpๆ "bar.php" ถูกเพิ่มเข้าที่ท้ายฐาน ในทางปฏิบัติตัวอย่างนี้มักจะไม่ใช่สิ่งที่คุณต้องการเพราะคุณไม่สามารถมีหลายฐานในที่เก็บไดเรกทอรีเดียวกันหรือไฟล์ htaccess
ในกรณีส่วนใหญ่จะใช้แบบนี้:
RewriteBase /subdir1/
RewriteRule ^foo$ bar.php [L]
โดยที่กฎเหล่านั้นจะอยู่ในไดเรกทอรี "subdir1" และ
RewriteBase /subdir2/subsubdir/
RewriteRule ^foo$ bar.php [L]
จะอยู่ในไดเรกทอรี "subsubdir"
ส่วนนี้ช่วยให้คุณสามารถทำให้กฎของคุณเป็นแบบพกพาได้ดังนั้นคุณสามารถวางกฎลงในไดเรกทอรีใดก็ได้และต้องการเปลี่ยนฐานแทนที่จะเป็นกฎจำนวนมาก ตัวอย่างเช่นถ้าคุณมี:
RewriteEngine On
RewriteRule ^foo$ /subdir1/bar.php [L]
RewriteRule ^blah1$ /subdir1/blah.php?id=1 [L]
RewriteRule ^blah2$ /subdir1/blah2.php [L]
...
เช่นที่http://example.com/subdir1/fooจะให้บริการhttp://example.com/subdir1/bar.phpฯลฯ และบอกว่าคุณตัดสินใจที่จะย้ายไฟล์และกฎเหล่านั้นทั้งหมดไปยังไดเรกทอรี "subsubdir" แทนที่จะเปลี่ยนทุกอินสแตนซ์/subdir1/เป็น/subdir2/subsubdir/คุณอาจมีเพียงฐาน:
RewriteEngine On
RewriteBase /subdir1/
RewriteRule ^foo$ bar.php [L]
RewriteRule ^blah1$ blah.php?id=1 [L]
RewriteRule ^blah2$ blah2.php [L]
...
และเมื่อคุณต้องการย้ายไฟล์เหล่านั้นและกฎไปยังไดเรกทอรีอื่นเพียงแค่เปลี่ยนฐาน:
RewriteBase /subdir2/subsubdir/
และนั่นคือมัน