htacces 2 ตัวแปรปัญหา
ก่อนที่ฉันจะติดตั้ง SSL สิ่งต่างๆทำงานได้อย่างสมบูรณ์ !! นี่คือรหัสที่ฉันมีในไฟล์. htaccess ของเว็บเซิร์ฟเวอร์รากของฉัน:
Options +MultiViews
RewriteEngine On
RewriteCond %{HTTP_HOST} andrea\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://andrea.com/$1 [R,L]
RewriteCond %{DOCUMENT_ROOT}/$1.php -f RewriteRule (.*) $1.php [L]
มันใช้งานได้และทำในสิ่งที่ฉันต้องการให้ทำ ดังนั้นถ้าฉันไปที่ตัวอย่าง:
www.andrea.com/account
เข้าถึง "www.andrea.com/account.php" ซึ่งเป็นสิ่งที่ฉันต้องการ อย่างไรก็ตามฉันมีโฟลเดอร์ในรูทชื่อ "products" มีไฟล์ ".htaccess" อีกไฟล์ในโฟลเดอร์นั้นและฉันไม่รู้ว่าจะต้องเปลี่ยนไฟล์ใดใน 2 ไฟล์นี้เพื่อให้สิ่งต่อไปนี้ทำงานได้
เมื่อคุณไปที่ URL นี้: http: ____ / products / view / Hello / Goodbye
ฉันต้องการให้เข้าถึง "view.php" ในโฟลเดอร์ "products" และในไฟล์ php นั้นฉันสามารถทำได้:
$id = $_GET["id"]; // This would have "Hello"
$cat = $_GET["cat"]; // This would have "Goodbye"
และใช้งานได้ดีเมื่อฉันใช้ htaccess นี้ในโฟลเดอร์ "products":
RewriteEngine on
RewriteCond %{HTTP_HOST} !^$ RewriteCond %{HTTP_HOST} !^www\. [NC] RewriteCond %{HTTPS}s ^on(s)| RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^([^/]*)/?(.*)$ /products/view.php?id=$1&cat=$2
ปัญหาเกี่ยวกับโค้ดด้านบนนี้คือถ้าฉันไปที่: http: ____ / products / Hello / Goodbye
ฉันต้องการให้เข้าถึง "index.php" ที่อยู่ในโฟลเดอร์ "products" แต่กลับไปที่ "view.php" แทน !! เหมือนกับว่าโค้ด htaccess ข้างบนบังคับให้ไปที่ view.php (ซึ่งควรทำก็ต่อเมื่อฉันมี "view / ____" ใน url ฉันต้องการให้ url ด้านบนไปที่ "index.php" ใน "ผลิตภัณฑ์ "และในไฟล์นั้นฉันควรจะสามารถเข้าถึงตัวแปร ID และ CAT ได้
มีแนวคิดเกี่ยวกับสิ่งที่ต้องเปลี่ยนแปลงในไฟล์. htaccess ของฉันหรือไม่ ขออภัยฉันใช้เวลานานกว่า 2 ชั่วโมงฉันไม่เข้าใจบรรทัดเดียวที่ด้านล่างของรหัส แต่ใช้ไม่ได้: /
คำตอบ
คุณสามารถใช้กฎต่อไปนี้จะเขียนไป/products/Hello/Goodbye/products/index.php
RewriteRule ^Hello/GoodBye/?$ /product/index.php?id=hello&cat=Goodbye [L,NC]
/product/.htaccessนี่คือที่สมบูรณ์ของคุณ
RewriteEngine on
RewriteCond %{HTTP_HOST} !^$
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
#rewrite /products/Hello/GoodBye to /products/index.php
RewriteRule ^Hello/GoodBye/?$ /products/index.php?id=Hello&cat=Goodbye [L,NC] ################### RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^([^/]*)/?(.*)$ /products/view.php?id=$1&cat=$2
Options +MultiViews
ก่อนอื่นคุณควรปิดใช้งาน MultiViews ในคำตอบของฉันที่คุณคำถามก่อนหน้านี้ข้อเสนอแนะของฉันที่จะใช้ MultiViews เป็นอย่างเคร่งครัดเป็น "ทางเลือก" วิธีการในบริบทของคำถามของคุณ คุณไม่สามารถใช้ทั้งสองวิธี (mod_rewrite และ MultiViews) เพื่อทำงานกับ URL ที่ไม่มีส่วนขยาย และเนื่องจากตอนนี้คุณต้องการทำสิ่งต่างๆมากขึ้นและส่งผ่านพารามิเตอร์ MultiViews จะสร้างความขัดแย้งเท่านั้น (MultiView มีแนวโน้ม "ชนะ" และไม่มีการส่งผ่านพารามิเตอร์ใด ๆ )
นอกจากนี้คุณต้องการ.htaccessไฟล์เพิ่มเติมโดยเฉพาะใน/productsไดเรกทอรีย่อยหรือไม่ การมี.htaccessไฟล์เดียวในรูทเอกสารจะง่ายกว่า (เนื้อหา) วิธีนี้จะหลีกเลี่ยงไม่ให้ต้องทำซ้ำการเปลี่ยนเส้นทาง HTTP เป็น HTTPS (แม้ว่าคุณจะไม่ได้รวมการเปลี่ยนเส้นทาง HTTP เป็น HTTPS ไว้ใน.htaccessไฟล์ไดเร็กทอรีย่อยก็ตาม)
# /products/.htaccess RewriteRule ^([^/]*)/?(.*)$ /products/view.php?id=$1&cat=$2
คำสั่งนี้จับคู่ทั้งสองอย่างview/Hello/Goodbye และ Hello/Goodbyeอธิบายว่าเหตุใดทุกอย่างจึงถูกเขียนลงในview.phpสคริปต์ของคุณ อย่างไรก็ตามมันไม่ได้ทำตามที่คุณพูดจริงๆ - ซึ่งทำให้งง หากคุณร้องขอ/products/view/Hello/Goodbyeระบบจะเขียนคำขอไปยัง/products/view.php?id=view&cat=Hello/Goodbye- ซึ่งไม่ใช่ความตั้งใจ (เว้นแต่จะเปิดใช้งาน MutliViews ซึ่งในกรณีนี้จะไม่มีการส่งผ่านพารามิเตอร์ใด ๆ เลย)
คุณต้องตรวจสอบจริงviewsใน URL views.phpที่ขอเส้นทางก่อนที่จะพยายามที่จะเขียนไป และถ้าviewsไม่มีให้เขียนใหม่index.phpแทน "การแยกตามเงื่อนไข" นี้สามารถทำได้โดยการจัดเรียงคำสั่งตามลำดับของกฎที่ "เฉพาะเจาะจงมากขึ้น" ก่อน
ตัวอย่างเช่นใน.htaccessไฟล์รูทของคุณให้ลองทำดังต่อไปนี้ (และลบ/products/.htaccessไฟล์ทั้งหมด)
# Ensure that MultiViews is disabled
Options -MultiViews
RewriteEngine On
# HTTP to HTTPS canonical redirect
RewriteCond %{HTTP_HOST} example\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule (.*) https://example.com/$1 [R=301,L]
# Abort early if the request already maps to (or looks like) a file or directory
RewriteCond %{REQUEST_URI} \.\w{2,4}$ [OR] RewriteCond %{REQUEST_FILENAME} -f [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^ - [L] # 1. Rewrite "/products/view/<id>/<cat>" to "/products/view.php?id=<id>&cat=<cat> RewriteRule ^(products/view)/([^/]*)/?(.*) $1.php?id=$2&cat=$3 [L]
# 2. Rewrite "/products/<id>/<cat>" to "/products/index.php?id=<id>&cat=<cat>
RewriteRule ^(products)/([^/]*)/?(.*) $1/index.php?id=$2&cat=$3 [L] # 3. Extensionless URLs for other requests RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule (.*) $1.php [L]
ลำดับของกฎ 3 ข้อข้างต้นมีความสำคัญ กฎที่เฉพาะเจาะจงที่สุดคืออันดับแรก รวมถึงLแฟล็กเพื่อป้องกันการประมวลผลเพิ่มเติม (ไม่จำเป็น)
โปรดทราบว่าตามคำสั่งเดิมของคุณสำหรับการร้องขอแบบฟอร์ม/products/view/Hello/Goodbye(หรือ/products/Hello/Goodbye) Hello/Goodbyeส่วนนั้นเป็นทางเลือกทั้งหมดและจะส่งผลให้พารามิเตอร์idและcatURL ถูกตั้งค่า แต่ว่างเปล่า
นอกจากนี้ตามคำสั่งเดิมของคุณคำขอของแบบฟอร์ม/products/view/Hello/Goodbye/foo/bar/bazจะส่งผลให้catพารามิเตอร์ URL ถูกตั้งค่าเป็นGoodbye/foo/bar/baz(อะไรก็ตามที่ตามหลังกลุ่มเส้นทางเริ่มต้น)
คุณไม่จำเป็นต้องตรวจสอบว่าคำขอแมปไปยังไฟล์หรือไดเร็กทอรี (ซึ่งมีราคาค่อนข้างแพง ) หากคุณทำให้ regex ของคุณมีความเฉพาะเจาะจงมากขึ้นและตรงกับสิ่งที่คุณต้องการเท่านั้น ตัวอย่างเช่น/([^/]*)/?(.*)ปัจจุบันregex ของคุณตรงกับทุกอย่าง แต่ถ้าตัวแปรของคุณ<id>และ<cat>สามารถประกอบด้วยตัวอักษรพิมพ์เล็กเท่านั้น (เช่น) สิ่งนี้อาจหลีกเลี่ยงความจำเป็นในการตรวจสอบระบบไฟล์
หมายเหตุอื่น ๆ :
- คุณต้องตรวจสอบชื่อโฮสต์ในการเปลี่ยนเส้นทาง HTTP เป็น HTTPS หรือไม่ คุณโฮสต์หลายโดเมนหรือไม่ มิฉะนั้นเงื่อนไขที่ตรวจสอบกับ
HTTP_HOSTตัวแปรเซิร์ฟเวอร์ก็ไม่จำเป็น