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/
และนั่นคือมัน