web-dev-qa-db-ja.com

RewriteBaseを現在のフォルダーパスに動的に設定します

ホストルートを基準にしたパスの現在のフォルダー(.htaccessファイルが含まれるフォルダー)にRewriteBaseを設定する方法はありますか?

私はCMSを持っていますが、それをホストのディレクトリに移動すると、RewriteBaseをホストのルートを基準にしたディレクトリのパスに設定しない限り機能しません。 htaccessのコードを変更せずに、コピーアンドペーストのみでCMSを機能させたいです。

更新:

例えば:

webroot

 - sub_directory
 - cms
 - .htaccess

この場合、私はhtaccessに書き込む必要があります:RewriteBase /

sub_directory内でhtaccessを移動する場合は、RewriteBaseを次のように変更する必要があります。

RewriteBase /sub_directory/

だから私は次のようなものが欲しい

RewriteBase /%{current_folder}/

21
Eeliya

これは、環境変数でRewriteBaseを取得して、他の書き換えルールで使用できる1つの方法です。

_RewriteCond %{REQUEST_URI}::$1 ^(.*?/)(.*)::\2$
RewriteRule ^(.*)$ - [E=BASE:%1]
_

次に、ルールで_%{ENV:BASE}_を使用して、RewriteBaseを示すことができます。つまり、次のようになります。

_#redirect in-existent files/calls to index.php
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteRule . %{ENV:BASE}/index.php [L]
_

説明:

このルールは、_REQUEST_URI_をRewriteRuleが参照するURLパスと比較することで機能します。これは、_REQUEST_URI_の先頭のRewriteBaseが削除されたものです。違いはRewriteBaseであり、_%{ENV:BASE}_に入れられます。

  • RewriteCondでは、LHS(テスト文字列)は後方参照変数を使用できます。 _$1_、_$2_ OR _%1_、_%2_など。ただしRHS側、つまり条件文字列使用できませんこれらの_$1_、_$2_ OR _%1_、_%2_変数。
  • RHS条件部分の内部では、使用できる後方参照のみが内部後方参照、つまり、この条件自体でキャプチャしたグループです。それらは_\1_、_\2_などで示されます。
  • RewriteCondで最初にキャプチャされたグループは_(.*?/)_です。これは、内部後方参照_\1_によって表されます。
  • このルールは、基本的に_%{REQUEST_URI}_と_$1_を比較することにより、動的にRewriteBaseを見つけることであることがわかります。 _%{REQUEST_URI}_の例は_/directory/foobar.php_になり、同じURIの例の_$1_の例は_foobar.php_になります。 ^(.*?/)(.*)::\2$は、最初にキャプチャされたグループ_%1_または_\1_に差を入れています。この例では、_%1_と_\1_に値_/directory/_を入力します。この値は、後で_%{ENV:BASE}_で環境変数_E=BASE:%1_を設定するときに使用されます。
41
anubhava

受け入れられた解決策は私にはうまくいかなかったと思いますが、これはうまくいきました: https://web.archive.org/web/20180401034514/http://www.zeilenwechsel.de/it/articles/8/ Using-mod_rewrite-in-.htaccess-files-without-knowing-the-RewriteBase.html

短編小説:

RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond $0#%{REQUEST_URI} ([^#]*)#(.*)\1$
RewriteRule ^.*$ %2index.php [QSA,L]
10
Dakusan

anubhavaの答えJon Linの に基づいて、これが私が思いついたものです(これを本番環境で使用したことも、まだ広範囲にテストしたこともありません)。

このURLの例を使用してみましょう。ここで、.htaccessはcurrent_folderにあります。

_http://localhost/path_to/current_folder/misc/subdir/file.xyz_

ファイルシステム:_/var/www/webroot/path_to/current_folder/.htaccess_

_Options +FollowSymLinks
RewriteEngine On
RewriteBase /

RewriteCond %{ENV:SUBPATH} ^$  # Check if variable is empty. If it is, process the next rule to set it.
RewriteRule ^(.*)$ - [ENV=SUBPATH:$1]
# SUBPATH is set to 'misc/subdir/file.xyz'

RewriteCond %{ENV:CWD} ^$
RewriteCond %{ENV:SUBPATH}::%{REQUEST_URI} ^(.*)::(.*?)\1$
RewriteRule ^ - [ENV=CWD:%2]
# CWD is set to '/path_to/current_folder/'

RewriteCond %{ENV:FILENAME} ^$
RewriteCond %{REQUEST_URI} ^.*/(.*)$
RewriteRule ^ - [ENV=FILENAME:%1]
# FILENAME is set to 'file.xyz'

# Check if /var/www/webroot/path_to/current_folder/misc/subdir/file.xyz exists.
# -f checks if a file exists, -d checks for a directory.
# If it exists, rewrite to /path_to/current_folder/misc/subdir/file.xyz and stop processing rules.
RewriteCond %{ENV:SUBPATH} ^.+$  # Ensure SUBPATH is not empty
RewriteCond %{DOCUMENT_ROOT}%{ENV:CWD}%{ENV:SUBPATH} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{ENV:CWD}%{ENV:SUBPATH} -d
RewriteRule ^.*$ %{ENV:CWD}%{ENV:SUBPATH} [END]

# Check if /var/www/webroot/path_to/current_folder/file.xyz exists.
# If it exists, rewrite to /path_to/current_folder/file.xyz and stop processing rules.
RewriteCond %{ENV:FILENAME} ^.+$
RewriteCond %{DOCUMENT_ROOT}%{ENV:CWD}%{ENV:FILENAME} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{ENV:CWD}%{ENV:FILENAME} -d
RewriteRule ^.*$ %{ENV:CWD}%{ENV:FILENAME} [END]

# Else, rewrite to /path_to/current_folder/index.html and stop processing rules.
RewriteRule ^.*$ %{ENV:CWD}index.html [END]
_

Apacheの_LogLevel alert rewrite:trace6_で_httpd.conf_を使用し、次に_error.log_を調べることで、自分で起こっていることの詳細を表示できます。

次の2行についてもう少し詳しく説明しますが、それでも少し混乱します。

_RewriteCond %{ENV:SUBPATH}::%{REQUEST_URI} ^(.*)::(.*?)\1$
RewriteRule ^ - [ENV=CWD:%2]
_

まず、二重コロン_::_はいかなる種類の演算子でもありません。これは単なる任意の区切り文字です。 RewriteCondは、TestString _%{ENV:SUBPATH}::%{REQUEST_URI}_を次のように展開します。

_misc/subdir/file.xyz::/path_to/current_folder/misc/subdir/file.xyz_

次に、CondPattern ^(.*)::(.*?)\1$

  1. ^(.*)::は_misc/subdir/file.xyz::_と一致します
  2. _\1_は最初のキャプチャグループ、_misc/subdir/file.xyz_です
  3. _(.*?)\1$_は_(.*?)misc/subdir/file.xyz$_になります
  4. したがって、2番目のキャプチャグループ_(.*?)_は残りの_/path_to/current_folder/_と一致します

そして、RewriteRuleCWDを_%2_に設定します。これはCondPatternの2番目のキャプチャグループです。

5
aplum