Nhóm RewriteRule theo RewriteCond với .htaccess

Apr 16 2020

Tôi có một mẫu trang web mà tôi sử dụng để chạy nhiều trang đích và htaccess được sử dụng để chuyển hướng URL thân thiện đến pageid trong mã PHP. Tất cả đều hoạt động nhưng hiện tại tôi phải thêm dòng điều kiện viết lại trước mọi quy tắc hoặc xung đột chuyển hướng. Bạn có thể thấy điều này trong mã giả bên dưới:

RewriteEngine On

RewriteCond for domain1
RewriteRule for page 1 on domain 1
RewriteCond for domain1
RewriteRule for page 2 on domain 1

RewriteCond for domain2
RewriteRule for page 1 on domain 2
RewriteCond for domain2
RewriteRule for page 2 on domain 2

Điều này không mở rộng quy mô tốt và nếu tôi đang làm điều này với bất kỳ ngôn ngữ nào khác, tôi sẽ nhóm các quy tắc như sau:

RewriteCond for domain1
{
    RewriteRule for page 1 on domain 1  
    RewriteRule for page 2 on domain 1
}

RewriteCond for domain2
{
    RewriteRule for page 1 on domain 2  
    RewriteRule for page 2 on domain 2
}

Nếu tôi có thể nhóm, nó sẽ làm cho tệp htaccess dễ quản lý hơn nhiều. Có cách nào để quy tắc nhóm không? Tôi đã thử tìm kiếm giải pháp nhưng mọi ví dụ tôi gặp đều thảo luận về 1 chuyển hướng cho 1 tên miền. Ý tưởng khác của tôi là tạo một tập lệnh htaccess bằng PHP / MySQL mà tôi nhập dữ liệu của mình, nhấn một nút và nó ghi tệp htaccess, nó sẽ phức tạp để đọc nhưng sẽ ổn. Tôi chắc rằng có một giải pháp đơn giản. Ai có thể giúp tôi không?

Trả lời

1 PlatformDating Apr 17 2020 at 09:54

Đây là giải pháp cuối cùng của tôi đang hoạt động trong sản xuất:

RewriteEngine On

<If "%{HTTP_HOST} == 'domain1.com'">        

        #main pages
        RewriteRule /members/$ /index.php?pageid=2 [NC,L] RewriteRule /contact/$    /index.php?pageid=3 [NC,L]
        RewriteRule /affiliates/$ /index.php?pageid=4 [NC,L] #blog articles RewriteRule /welcome-to-our-blog/$ /index.php?pageid=b0001 [NC,L]
</If>


<If "%{HTTP_HOST} == 'domain2.com'">        

        #main pages
        RewriteRule /about/$ /index.php?pageid=2 [NC,L] RewriteRule /press-kit/$    /index.php?pageid=3 [NC,L]
        RewriteRule /contact/$ /index.php?pageid=4 [NC,L] RewriteRule /affiliates/$   /index.php?pageid=5 [NC,L]

        #blog articles
        RewriteRule /welcome-to-our-blog/$ /index.php?pageid=b0001 [NC,L]
</If>
MrWhite Sep 22 2020 at 16:28

Một vài lựa chọn thay thế cho việc sử dụng <If>các phần, vì không phải là không có những lưu ý của nó .

  1. Bỏ qua các lệnh khi điều kiện không khớp (hoặc không) khớp
  2. Đặt tiền tố URL (để khớp) với tên máy chủ
  3. .htaccessTệp cấu hình riêng biệt cho từng máy chủ

( Bên cạnh: Bạn có thực sự muốn kết hợp - - không phân biệt chữ hoa chữ thường không NC?)

1. Bỏ qua chỉ thị khi điều kiện khớp (hoặc không) khớp

Bạn có thể bỏ qua ( Sgắn cờ) bất kỳ số lượng lệnh nào khi quy tắc (hoặc điều kiện) không khớp. I E. Nếu bạn bỏ qua các quy tắc tuân theo khi HTTP_HOSTkhông có domain1.comthì các quy tắc sau chỉ được xử lý khi HTTP_HOSTdomain1.com.

Ví dụ:

# Skip the following 4 rules when the host is not "domain1.com"
RewriteCond %{HTTP_HOST} !=domain1.com
RewriteRule ^ - [S=4]

# Only processed when the HTTP_HOST is equal to "domain1.com"

#main pages
RewriteRule ^members/$ /index.php?pageid=2 [NC,L] RewriteRule ^contact/$     /index.php?pageid=3 [NC,L]
RewriteRule ^affiliates/$ /index.php?pageid=4 [NC,L] #blog articles RewriteRule ^welcome-to-our-blog/$ /index.php?pageid=b0001 [NC,L]

# --------------------------------------------------------------------

# Skip the following 5 rules when the host is not "domain2.com"
RewriteCond %{HTTP_HOST} !=domain2.com
RewriteRule ^ - [S=5]

# Only processed when the HTTP_HOST is equal to "domain2.com"

#main pages
RewriteRule ^about/$ /index.php?pageid=2 [NC,L] RewriteRule ^press-kit/$   /index.php?pageid=3 [NC,L]
RewriteRule ^contact/$ /index.php?pageid=4 [NC,L] RewriteRule ^affiliates/$  /index.php?pageid=5 [NC,L]

#blog articles
RewriteRule ^welcome-to-our-blog/$ /index.php?pageid=b0001 [NC,L]

Mặc dù một lưu ý rõ ràng với cách tiếp cận này là bạn cần phải cẩn thận cập nhật S=<number>cờ khi thêm hoặc xóa bất kỳ quy tắc nào.

Rõ ràng là bạn có thể đảo ngược logic để có những gì trông giống như mục lục ở trên cùng. Ví dụ:

RewriteCond %{HTTP_HOST} =domain1.com
RewriteRule ^ - [S=2]
RewriteCond %{HTTP_HOST} =domain2.com
RewriteRule ^ - [S=5]
RewriteCond %{HTTP_HOST} =domain3.com
RewriteRule ^ - [S=9]

# --------------------------------------------------------------------
# domain1.com

#main pages
RewriteRule ^members/$     /index.php?pageid=2 [NC,L]
RewriteRule ^contact/$ /index.php?pageid=3 [NC,L] RewriteRule ^affiliates/$  /index.php?pageid=4 [NC,L]

#blog articles
RewriteRule ^welcome-to-our-blog/$ /index.php?pageid=b0001 [NC,L] # -------------------------------------------------------------------- # domain2.com #main pages RewriteRule ^about/$       /index.php?pageid=2 [NC,L]
RewriteRule ^press-kit/$ /index.php?pageid=3 [NC,L] RewriteRule ^contact/$     /index.php?pageid=4 [NC,L]
RewriteRule ^affiliates/$ /index.php?pageid=5 [NC,L] #blog articles RewriteRule ^welcome-to-our-blog/$ /index.php?pageid=b0001 [NC,L]

Mặc dù các quy tắc "bỏ qua" có khả năng dễ bị lỗi hơn vì bạn có thể cần cập nhật một số khi thêm hoặc xóa các quy tắc, tùy thuộc vào vị trí của các quy tắc này.

2. Đặt tiền tố URL (để khớp) với tên máy chủ

Ngoài ra, bạn có thể (tạm thời) đặt tiền tố đường dẫn URL bằng tên máy chủ và đối sánh với tên này trong các quy tắc theo sau. Điều này tránh RewriteCondchỉ thị bổ sung trong tất cả các quy tắc tiếp theo.

Ví dụ:

# Prefix URL-path with HTTP_HOST if not already prefixed / No "L" flag
RewriteCond %{HTTP_HOST}@$1 !^([a-z.-]+)@\1 RewriteCond %{REQUEST_FILENAME} !-f RewriteRule (.*) %{HTTP_HOST}/$1

# --------------------------------------------------------------------
# domain1.com

#main pages
RewriteRule ^domain1\.com/members/$ /index.php?pageid=2 [NC,L] RewriteRule ^domain1\.com/contact/$     /index.php?pageid=3 [NC,L]
RewriteRule ^domain1\.com/affiliates/$ /index.php?pageid=4 [NC,L] #blog articles RewriteRule ^domain1\.com/welcome-to-our-blog/$ /index.php?pageid=b0001 [NC,L]

# --------------------------------------------------------------------
# domain2.com

#main pages
RewriteRule ^domain2\.com/about/$ /index.php?pageid=2 [NC,L] RewriteRule ^domain2\.com/press-kit/$   /index.php?pageid=3 [NC,L]
RewriteRule ^domain2\.com/contact/$ /index.php?pageid=4 [NC,L] RewriteRule ^domain2\.com/affiliates/$  /index.php?pageid=5 [NC,L]

#blog articles
RewriteRule ^domain2\.com/welcome-to-our-blog/$ /index.php?pageid=b0001 [NC,L]

Điều này tránh RewriteCondchỉ thị bổ sung , tuy nhiên, nó yêu cầu bạn đặt tiền tố đường dẫn URL phù hợp với miền trong mỗi trường hợp. Ít khả năng xảy ra lỗi hơn so với việc sử dụng Scờ như trong ví dụ đầu tiên ở trên.

Trong ví dụ trên, tên máy chủ vẫn được đặt tiền tố cho đường dẫn URL ở cuối yêu cầu cho bất kỳ URL nào không ánh xạ trực tiếp đến tệp hoặc không được ghi lại /index.php?pageid=<number>. Điều này sau đó sẽ dẫn đến 404.

Nếu bạn đặc biệt muốn xóa tiền tố tên máy chủ (có lẽ bạn đang sử dụng $_SERVER['REDIRECT_URL']biến trong tài liệu lỗi của mình, ngược lại $_SERVER['REQUEST_URI']) thì bạn có thể thực hiện việc này bằng cách giới thiệu một biến môi trường bổ sung (hãy gọi nó FINISHED) và xóa tiền tố này ở cuối.

Ví dụ, sửa đổi quy tắc đầu tiên để kiểm tra FINISHEDenv var (không tồn tại ban đầu) và giới thiệu một quy tắc mới ở cuối loại bỏ tiền tố và đặt env var. Nếu không có FINISHEDenv var, chúng tôi sẽ gặp khó khăn trong vòng lặp viết lại cho "URL không xác định" vì nó sẽ lặp lại tiền tố và xóa tên máy chủ trên đường dẫn URL.

# Prefix URL-path with HTTP_HOST if not already prefixed and not FINISHED / No "L" flag
RewriteCond %{ENV:FINISHED} ^$
RewriteCond %{HTTP_HOST}@$1 !^([a-z.-]+)@\1 RewriteCond %{REQUEST_FILENAME} !-f RewriteRule (.*) %{HTTP_HOST}/$1

# :
# : Directives for each domain go here (as above)
# :

# Tidy up - remove the HTTP_HOST prefix and set FINISHED env var
RewriteCond %{HTTP_HOST}@$1 ^([a-z.-]+)@\1/(.*)
RewriteRule (.*) %2 [E=FINISHED:1,L]

3. .htaccessTệp cấu hình riêng biệt cho từng máy chủ

Một giải pháp thay thế khác có lẽ phù hợp hơn với tình huống cụ thể này của các miền riêng biệt và các trang web riêng biệt về cơ bản (mặc dù có lẽ là một công cụ "chung" ) là có .htaccesscác tệp bổ sung (riêng biệt) cho mỗi trang web.

Chính xác cách bạn định cấu hình điều này có thể phụ thuộc vào chính xác cách bạn đã định cấu hình cấu trúc tệp của mình, tuy nhiên, điều này cho phép tăng sự tách biệt giữa các trang web của bạn và thậm chí chia sẻ cấu hình giữa hai hoặc nhiều trang web nếu bạn muốn. Bạn có thể có các tài nguyên chỉ liên quan đến trang web đang được truy cập - nhưng bạn có thể đã có những thứ như thế này rồi.

Ví dụ...

  • Bạn sẽ vẫn có .htaccesstệp "chính" trong gốc tài liệu (giả sử bạn chia sẻ một thư mục gốc chung cho tất cả các miền).
  • Tạo một thư mục con cho mỗi máy chủ. ví dụ. /domain1.comvà bên trong mỗi thư mục con, bạn chỉ có một .htaccesstệp cho miền đó.

Cấu trúc tệp:

/
    domain1.com/
        .htaccess
    domain2.com/
        .htaccess
    .htaccess
    index.php

/.htaccess

Sau đó, .htaccesstệp gốc sẽ định tuyến yêu cầu đến thư mục con thích hợp cho máy chủ được yêu cầu.

RewriteEngine On

# If the request is already for index.php in the document root then DONE
RewriteRule ^index\.php$ - [L]

# Rewrite all requests that don't map to files to the appropriate domain subdirectory
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) %{HTTP_HOST}/$1 [L]

/domain1.com/.htaccess

Sau đó, .htaccesstệp của mỗi miền chỉ chứa các chỉ thị cho miền đó và viết lại yêu cầu trở lại /index.phptệp "chung" trong gốc tài liệu để hiển thị yêu cầu.

Các lệnh viết lại có cùng định dạng "bình thường" như được sử dụng ở trên.

# domain1.com

RewriteEngine On

# Optional - If this subdirectory is accessed directly then redirect back to the root
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.*) /$1 [R=301,L] #main pages RewriteRule ^members/$     /index.php?pageid=2 [NC,L]
RewriteRule ^contact/$ /index.php?pageid=3 [NC,L] RewriteRule ^affiliates/$  /index.php?pageid=4 [NC,L]

#blog articles
RewriteRule ^welcome-to-our-blog/$ /index.php?pageid=b0001 [NC,L]

Dù sao, thức ăn cho sự suy nghĩ. Một số điều này phụ thuộc vào cách bạn cấu trúc ứng dụng của mình chứ không phải là "Phân nhóm RewriteRule theo RewriteCond". Nếu bạn muốn giải thích thêm về bất kỳ "bit" nào thì chỉ cần nói.