การใช้ mod_rewrite ถึง 301 เปลี่ยนเส้นทางรับ vars ไปยัง URL ใหม่ที่ปลอดภัย

อัปเดต: วิธีแก้ปัญหาที่ด้านล่าง

ฉันเพิ่งเปลี่ยนจากการใช้การตั้งค่าเช่น index.php?p=page_name&o=temporary_override และเปลี่ยนไปใช้ URL ที่ปลอดภัยเช่น /page_name/temporary_override การแทนที่ชั่วคราวเป็นเพียงเพื่อให้ฉันเห็นผลลัพธ์ของการเปลี่ยนแปลงไซต์ในขณะที่กำลังสร้าง

ขณะนี้ฉันได้ตั้งค่า mod_rewrite เป็น:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?GHPAGE=$1 [L,QSA]

ซึ่งจะจับ "ไดเรกทอรีย่อย" จากนั้น PHP จะแยกวิเคราะห์ URL จาก GHPAGE $_GET var สิ่งที่ฉันต้องการคือตั้งค่าการเปลี่ยนเส้นทาง 301 เพื่อให้ใครก็ตามที่ใช้ index.php?p=something&o=something_else จะถูกเปลี่ยนเส้นทางไปที่ /something/something_else มีความคิดใดที่ฉันจะทำสิ่งนี้ให้สำเร็จได้อย่างไร? p & o อาจมาในลำดับใดก็ได้และอย่างใดอย่างหนึ่งอาจไม่มีอยู่

แก้ไข: ตกลง หลังจากความช่วยเหลือจาก @Jon-Lin, @dambrisco และ @anubhava ฉันก็เข้าใกล้มากขึ้น ไฟล์ .htaccess ของฉันตอนนี้ดูเหมือนว่า:

RewriteEngine On
#Base Directory
RewriteBase /test/

#if 2 GET Vars
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ \/([^\/]+\/)*(index\.php)?\?[op]=([^&]+)&[op]=(.+)\ HTTP\/
RewriteRule ^index\.php$ /%4/%5 [R=301,L]
#if 1 GET Var
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ \/([^\/]+\/)*(index\.php)?\?[op]=(.+)\ HTTP\/
RewriteRule ^index\.php$ /%4 [R=301,L]
#Remove index.php
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ \/([^\/]+\/)*index\.php\ HTTP\/
RewriteRule ^index\.php$ / [R=301,L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?GHPAGE=$1 [L,QSA]

ขณะนี้กำลังเปลี่ยนเส้นทาง แต่ยังไม่ถึงจุดที่จำเป็นต้องไป root/test/index.php?p=test&o=override เปลี่ยนเส้นทางไปที่ root/test/override?p=test&o=override แล้ว ใกล้กว่านี้ แต่ฉันไม่สามารถทราบวิธีกำจัด GET vars ที่ถูกเพิ่มลงใน URL หรือเหตุใดจึงเปลี่ยนเส้นทางไปยังไดเร็กทอรีรูทแทนที่จะไปยังไดเร็กทอรี RewriteBase

แก้ไข:

ขณะนี้มีการเปลี่ยนเส้นทางอย่างถูกต้อง แต่ด้วยเหตุผลบางอย่าง ทำให้โฟลเดอร์ /test/ RewriteBase หลุดออกจากสมการ http://www.domain.com/test/index.php?p=page1&o=operation กำลังถูกเปลี่ยนเส้นทางไปที่ http://www.domain.com/page1/operation ไฟล์ .htaccess ใหม่อยู่ด้านล่าง:

RewriteEngine On

RewriteBase /test/

#if 2 GET Vars
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ /([^/]+/)*(index\.php)?\?[op]=([^&]+)&[op]=(.+)\ HTTP\/
RewriteRule ^ /%4/%5? [R=301,L]

#if 1 GET Var
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ /([^/]+/)*(index\.php)?\?[op]=(.+)\ HTTP\/
RewriteRule ^ /%4? [R=301,L]

#if index.php
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ \/([^\/]+\/)*index\.php\ HTTP\/
RewriteRule ^index\.php$ /$ [L,R=301]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?GHPAGE=$1 [L,QSA]

ขอบคุณทุกคน. คำถามได้รับการแก้ไขแล้ว สุดท้าย .htaccess อยู่ด้านล่างสำหรับการอ้างอิง

RewriteEngine On

RewriteBase /test/

#if 2 GET Vars
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ /([^/]+/)*(index\.php)?\?[op]=([^&]+)&[op]=(.+)\ HTTP\/
RewriteRule ^ %4/%5? [R=301,L]

#if 1 GET Var
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ /([^/]+/)*(index\.php)?\?[op]=(.+)\ HTTP\/
RewriteRule ^ %4? [R=301,L]

#if index.php
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ \/([^\/]+\/)*index\.php\ HTTP\/
RewriteRule ^index\.php$ ? [L,R=301]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?GHPAGE=$1 [L,QSA]

person mtylerb    schedule 08.02.2012    source แหล่งที่มา


คำตอบ (3)


เพิ่มสิ่งนี้ที่ไหนสักแห่งใน htaccess ของคุณ:

RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ /index\.php\?p=([^&]+)&o=(.+)\ HTTP
RewriteRule index.php /%2/%3 [R=301,L]

และหากคุณต้องการครอบคลุมกรณีที่ไม่มี "temporary_override" ให้เพิ่มสิ่งนี้ด้วย:

RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ /index\.php\?p=(.+)\ HTTP
RewriteRule index.php /%2 [R=301,L]

ใกล้กว่านี้ แต่ฉันไม่สามารถทราบวิธีกำจัด GET vars ที่ถูกเพิ่มลงใน URL หรือเหตุใดจึงเปลี่ยนเส้นทางไปยังไดเร็กทอรีรูทแทนที่จะไปยังไดเร็กทอรี RewriteBase

เพิ่ม ? ที่ส่วนท้ายของ /%4/%5 เพื่อกำจัดสตริงข้อความค้นหา และลบ / นำหน้าออกจาก /%4/%5 เพื่อป้องกันไม่ให้เขียนซ้ำจนถึงราก ตัวอย่างเช่น กฎข้อหนึ่งของคุณควรมีลักษณะดังนี้:

RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ \/([^\/]+\/)*(index\.php)?\?[op]=([^&]+)&[op]=(.+)\ HTTP\/
RewriteRule ^index\.php$ %4/%5? [R=301,L]
person Jon Lin    schedule 08.02.2012
comment
คุณอาจต้องการใช้ RewriteRule ^index/.php$ /%2/%3 [R=301,L] - person anubhava; 08.02.2012
comment
คุณหมายถึง ^index\.php$ - จู้จี้จุกจิกเล็กน้อย - person Dan Ambrisco; 08.02.2012
comment
ดูเหมือนไม่ได้ทำอะไรเลย ขณะนี้ใช้โค้ดโดย @JonLin พร้อมกับการเพิ่มของ @dambrisco เพื่อสร้าง RewriteRule ^index\.php$ /%2/%3 [R=301,L] การเยี่ยมชมไซต์ด้วย index.php?p=l&o=override ไซต์ไม่เปลี่ยนเส้นทางไปที่ /l/override ขอบคุณสำหรับความช่วยเหลือจนถึงตอนนี้ - person mtylerb; 08.02.2012
comment
หลังจากค้นหาและรับผลลัพธ์ของสิ่งที่ THE_REQUEST ส่งคืนมาเล็กน้อย ดูเหมือนว่า: GET /test/index.php?p=test&o=override HTTP/1.0 ฉันเข้าใจ %{THE_REQUEST} ^([A-Z]{3,9})\ แต่นี่คือจุดที่ฉันรู้สึกสับสน ควรหลีกเลี่ยง '/' ที่อยู่หน้า index.php เช่น \/index\.php หรือไม่ ฉันเห็นว่า cPanel ได้หลีกเลี่ยง '/' จำนวนมากในการเปลี่ยนเส้นทาง 301 อื่นๆ สำหรับโดเมนอื่นบนเซิร์ฟเวอร์ของฉัน นอกจากนี้ \?p=([^&]+)&o=(.+)\ HTTP มันควรจะเป็น \?(p|o)=([^&]+)&(p|o)=(.+)\ HTTP(.{0,4}) ใช่ไหม? นั่นจะอนุญาตให้ตัวแปร get ไปในลำดับใดลำดับหนึ่งหรือไม่? ขอบคุณอีกครั้ง! - person mtylerb; 08.02.2012
comment
สุดยอดครับ เกือบไปแล้ว ฉันพลาดการอัปเดตคำตอบนี้ ตอนนี้ปัญหาเดียวคือ http://www.domain.com/test/index.php กำลังเปลี่ยนเส้นทางไปที่ http://www.domain.com/ แทนที่จะเป็น http://www.domain.com/test/ - person mtylerb; 09.02.2012
comment
RewriteRule ^index\.php$ /$ [L,R=301] ควรพูดว่า RewriteRule ^index\.php$ /test/ [L,R=301] หรือ RewriteRule ^index\.php$ ? [L,R=301] เพื่อสะท้อนถึงการเปลี่ยนแปลง (การลบเครื่องหมายทับนำหน้า) ไปยังกฎอื่นๆ - person Jon Lin; 09.02.2012

คุณจะต้องการใช้สิ่งต่อไปนี้:

RewriteRule ^([^/]+)/?$ index.php?p=$1 [L,QSA]
RewriteRule ^([^/]+)/([^/]+)/?$ index.php?p=$1&o=$2 [L,QSA]

ด้วยวิธีนี้ example.com/page_name จะถูกส่งผ่านภายในไปยัง index.php?p=page_name และ example.com/page_name/operation จะถูกส่งผ่านไปยัง index.php?p=page_name&o=operation คำตอบของจอน ลินดูเหมือนจะตรงกันข้าม ซึ่งฉันไม่ได้สังเกตเห็นเมื่อคืนนี้

ไม่จำเป็นต้องมี RewriteConds ใด ๆ ยกเว้นเพื่อหลีกเลี่ยงความขัดแย้งกับกฎอื่น ๆ ที่คุณอาจมีเพียงเพื่อชี้แจง

person Dan Ambrisco    schedule 08.02.2012
comment
หากฉันอ่านอย่างถูกต้อง สิ่งเหล่านั้นจะส่งผลต่อ URL ที่พิมพ์ถูกต้องเท่านั้น สิ่งที่ฉันต้องการทำคือ 301 เปลี่ยนเส้นทาง URL สกปรกเก่าไปยัง URL ใหม่ที่ปลอดภัย เช่นเดียวกับใน /?p=test&o=override 301=› /test/override - person mtylerb; 09.02.2012
comment
อา แย่จัง ฉันเข้าใจผิดปัญหา ตอนนี้คำตอบของ Jon Lin สมเหตุสมผลมากขึ้น ฉันจะดูสิ่งนี้อีกครั้งในภายหลังหากยังไม่ได้รับการแก้ไข - person Dan Ambrisco; 09.02.2012

การเปลี่ยนแปลง 2 บรรทัด RewriteRule ของคุณควรลงท้ายด้วย ? ดังนี้:

#if 2 GET Vars
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ /([^/]+/)*(index\.php)?\?[op]=([^&]+)&[op]=(.+)\ HTTP\/
RewriteRule ^ /%4/%5? [R=301,L]

#if 1 GET Var
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ /([^/]+/)*(index\.php)?\?[op]=(.+)\ HTTP\/
RewriteRule ^ /%4? [R=301,L]
person anubhava    schedule 08.02.2012
comment
ใกล้กว่านี้ มันใช้งานได้ดี แต่ตอนนี้กำลังเปลี่ยน URL จาก /test/index.php?p=test&o=override เป็น /?GHPAGE=test/override แก้ไข: ไม่เป็นไร มันตัดสินใจที่จะเริ่มเล่นได้ดี มันยังคงทิ้งโฟลเดอร์ RewriteBase ออกจากสมการ /test/index.php?p=test&o=override กำลังกลายเป็น root/test/override/ เมื่อควรจะเป็น root/test/test/override/ มีความคิดอะไรบ้าง? ฉันจะอัปเดต .htaccess ของฉันด้านบน - person mtylerb; 09.02.2012