htacces 2 ตัวแปรปัญหา

Nov 26 2020

ก่อนที่ฉันจะติดตั้ง 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 ชั่วโมงฉันไม่เข้าใจบรรทัดเดียวที่ด้านล่างของรหัส แต่ใช้ไม่ได้: /

คำตอบ

1 AmitVerma Nov 26 2020 at 11:35

คุณสามารถใช้กฎต่อไปนี้จะเขียนไป/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
1 MrWhite Nov 27 2020 at 07:13
 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ตัวแปรเซิร์ฟเวอร์ก็ไม่จำเป็น