web-dev-qa-db-ja.com

URLを書き換える複数のルール

なぜ両方のルールが一緒に機能しないのですか?どうすれば修正できますか?最初の1つだけが機能します... 2つのルール間に矛盾があると思いますが、まだ解決策が見つかりませんでした

?p=は、Webサイトのメインディレクトリにあるファイルにアクセスするために使用するクエリ文字列です。?page=はサブディレクトリ用です。

私の現在のURLは次のとおりです。

https://example.com/?p=home
https://example.com/?page=article
https://example.com/?page=article&tab=2

そして、私はそれになりたい:

https://example.com/home
https://example.com/article
https://example.com/article/2

.htaccess:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)$ index.php?p=$1 [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)$ index.php?page=$1 [L]
3
Derp Dee Derp

はい、競合があります。

  • 両方の.htaccessルールの条件はまったく同じであるため、最初のルールが常に勝ちます。 2番目は実行されません。
  • URL構造があいまいです。

コードを作成する前に、次のURLをどのようにyou解決するか、一歩後退する必要があります。

  • https://example.com/home
  • https://example.com/article
  • https://example.com/foo

home?p=homeに解決し、article?page=articleに解決する必要があることをどのように知っていますか? fooはどうですか? URLの内容のみを「見る」ことができます。

次のいずれかが必要です。

  • URLにはいくつかの識別可能な違いがあるので、それを書き換える方法を知っています。例:example.com/p/home vs example.com/pg/home
  • ?p=(または?page=)に書き換えられたURLの数が制限されている場合、ディレクティブのURLパターンを文字通りリストできます。そして、他のすべては?page=(または?p=)に送られます。例えば:

    RewriteRule ^(home|about)$ index.php?p=$1 [L]
    :
    RewriteRule ^([^/]+)$ index.php?page=$1 [L]
    
  • everythingを単一のURLパラメーター(例:?page=)に書き換え、PHPでページの表示方法を決定します務めた。とにかく両方のシナリオでindex.phpに書き換えており、.htaccessを編集し続ける必要がないので、これはより論理的なソリューションのようです。これは、追加のtab「パラメーター」も処理できます。

追加の「タブ」パラメーター

2番目のパスセグメントを持つすべてのURLを?page=に書き換える必要がある場合、「識別可能な」違いになる可能性があります。ただし、現在、/articleのように、2番目のパスセグメントが省略されていると失敗します。これはどのように処理する必要がありますか?

?page=へのファイルはサブディレクトリにあり、URLは次のようになります:https://example.com/news-folder/article

あなたの質問はサブディレクトリを参照していません。これは、URLの「タイプ」を区別し、URLを異なる方法で書き換えることができるのに十分です。

例えば:

RewriteEngine On

# Stop processing if the request looks like it maps to a physical resource
RewriteCond %{REQUEST_URI} \.(?:gif|jpg|png|css|js)$ [OR]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]

# Single path segment rewrite to ?p=
RewriteRule ^([^/]+)$ index.php?p=$1 [L]

# Requests for files in the subdirectory rewrite to ?page=
RewriteRule ^news-folder/([^/]+)$ index.php?page=$1 [L]

# Requests for files in the subdirectory with additional numeric "tab"
RewriteRule ^news-folder/([^/]+)/(\d+)$ index.php?page=$1&tab=$2 [L]

空のtabパラメーターがあれば、最後の2つのルールを組み合わせることができます。例えば。 example.com/news-folder/articleexample.com/index.php?page=article&tab=に書き換えられます。現状では、ディレクティブは独立しているため、/2(たとえば)が追加されていない場合、tabパラメーターはまったく存在しません。

PDATE:記事ページのターゲットに使用する正規表現にさらに制限がある場合は、ファイルシステムのチェック(静的リソースおよび書き換えループの防止)を完全に省略できます。例えば:

RewriteEngine On

# Single path segment rewrite to ?p=
RewriteRule ^([^/.]+)$ index.php?p=$1 [L]

# Requests for files in the subdirectory rewrite to ?page=
RewriteRule ^news-folder/([^/.]+)$ index.php?page=$1 [L]

# Requests for files in the subdirectory with additional numeric "tab"
RewriteRule ^news-folder/([^/.]+)/(\d+)$ index.php?page=$1&tab=$2 [L]

これは、ページへのURLに.(ドット)を含めることができないことを意味します。より制限が厳しく、Word文字(およびハイフン)のみを許可し、[^/.]+[\w-]+に変更できます。これにより、0-9a-zA-Z_、および-の文字のみで構成される記事名が許可されます。

サブディレクトリ/news-folderを完全に汎用化し、任意のサブディレクトリに一致させることができます。例えば:

RewriteRule ^\w+/(\w+)$ index.php?page=$1 [L]

これで、/<something>/articleのリクエストはすべてindex.php?page=articleに書き換えられます。

2
MrWhite