htaccessでURLが変わる

Oct 20 2020

私はいくつかの典型的なURLアドレスでウェブプレゼンテーションをしています。次に、さまざまな言語のリライターを追加する必要があります。例:

domain/club -> do not change
domain/club/path -> do not change
domain/club/path?search=somethingelse -> do not change
domain/en/club -> domain/club?lang=en
domain/en/club/path -> domain/club/path?lang=en
domain/en/club/path?search=something -> domain/club/path?search=something&lang=endomain

私のアイデアは、それをドメイン/言語/クラブ/パス?検索=何かのグループに分けてから書くことでした

RewriteRule \/(?<language>[a-zA-Z]{2})\/club\/?(?<path>.*)\?(?<search>.*)   /club/$1?search=$2&lang=$3

ただし、これは。のない文字列は考慮しません?。また、2つのケース?lang=との違いを解決する方法もわかりません&lang=。オンラインで何も見つかりませんでした。

私は既存のPHPフレームワーク(標準ではない)でこれを行っているので、この方法で行う必要があります(これらの特定のURLを理解してください)。

回答

3 MrWhite Oct 20 2020 at 00:36

これを実際よりも複雑にしているようです。「クラブ」のマッチングについて具体的に説明する必要がない限り、2文字の言語コードのように見える最初のパスセグメントを削除し、lang代わりにクエリ文字列のURLパラメータに移動する必要があるようです。

このために、.htaccessファイルの先頭近くで次のことを行うことができます。

RewriteRule ^([a-z]{2})/(.+) $2?lang=$1 [QSA,L]

要求/en/clubに書き換えられます/club?lang=enと/en/club/path?search=somethingまでは/club/path?lang=en&search=something(注意langURLパラメータが最初です)。

説明:

  • RewriteRule パターンは、 URLパスだけではなく、クエリ文字列に対して一致します。一致するURLパスにもスラッシュプレフィックスはありません。
  • ([a-z]{2})--2文字(小文字)の言語コードに一致します。(正規表現では大文字も許可しましたか?)これはキャプチャサブパターンであるため、(最初の)$1後方参照に自然に格納されます。
  • (.+)言語コード経路セグメント(スラッシュ)を以下のURLパス内のすべてを一致。これは、何もないのではなく、何かに一致することに注意してください。だから、への要求のために成功しませんだけで、。(このニーズが成功する場合のみだけでなく、その後に、このサブパターンを変更する。)これはまた、捕捉及び(第2)に格納される後方参照。例えば。リクエストして保持します。/en//en/<something>/en/ (.*)$2/en/club/path$2club/path
  • このQSAフラグは、最初のリクエストに存在する可能性のあるクエリ文字列を追加し、置換文字列内のクエリ文字列との「マージ」を処理します。例えば。search=something。ただし、例とのわずかな違いは、langURLパラメータが最後ではなく最初になることです。ただし、これは問題にはなりません。

ただし、これが機能するかどうかは、「PHPフレームワーク」がURLをルーティングする方法に依存します。たとえば、WordPressのようで、$_SERVER['REQUEST_URI']PHPスーパーグローバルを見ると、書き換え前のURLパスが表示されます。

あなたはおそらくこれに続く他の書き直しを持っていますか?


RewriteRule \/(?<language>[a-zA-Z]{2})\/club\/?(?<path>.*)\?(?<search>.*) /club/$1?search=$2&lang=$3

ただし、これは。のない文字列は考慮しません?。また、2つのケース?lang=との違いを解決する方法もわかりません&lang=。オンラインで何も見つかりませんでした。

ここにはいくつかの問題があります。

  • 正規表現はURLパスの先頭に固定されていないため、一致します /<anything>/en/etc.
  • 上記のように、RewriteRule パターンに一致するURLパスはスラッシュで始まりません。
  • 「これは「」のない文字列を考慮しません?-RewriteRule パターンに一致するURLはURLパスのみです。これにはクエリ文字列は含まれません。したがって、ここでクエリ文字列を照合しようとすると、単に失敗します。(クエリ文字列を照合する必要がある場合は、追加のRewriteCondディレクティブが必要であり、QUERY_STRINGサーバー変数と照合します。)
  • エラーではありませんが、スラッシュはここでは特別な意味を持たないため、正規表現でスラッシュをバックスラッシュエスケープする必要はありません(スペースはApache構成ファイルの正規表現/引数の区切り文字です)。前述のように、これは厳密にはエラーではありません。ほとんどの文字をバックスラッシュエスケープできるのと同じですが、正規表現が複雑になり、読みにくくなります。
  • 名前付きキャプチャグループ(Apache 2.4.8以降でサポート)を使用していますが、置換文字列で数値の後方参照を使用しています。両方を使用することはできません。(数値の後方参照IMOを使用する方が簡単です。)
  • 置換文字列の後方参照の順序が間違っているようです。$1言語コードです。例えば。それはもっと似ているはずです(これはまだ正しくありませんが)。/club/$2?search=$3&lang=$1
  • 「2つのケースで違いを解決する方法?lang=と&lang=」- QSA(Query String Append)フラグがこれを行います。クエリ文字列がプレフィックスではなく追加されることを除いて。