Dynamicznie ustawia bazę RewriteBase na bieżącą ścieżkę folderu

Czy Jest jakiś sposób, aby ustawić RewriteBase do bieżącego folderu ścieżki (folderu, któryplik htaccess jest w) względem głównego hosta?

Mam CMS i jeśli przeniosę go do katalogu na moim hoście, nie działa, chyba że ustawię bazę przepisywania na ścieżkę katalogu względem głównego hosta. Chciałbym, aby mój CMS działał tylko z kopiuj i wklej, bez zmiany kodu w htaccess.

Aktualizacja:

Na przykład:

webroot

 - sub_directory
 - cms
 - .htaccess

W tym przypadku powinienem napisać w htaccess: RwriteBase /

I jeśli przeniosę htaccess do sub_directory powinienem zmienić RwriteBase na:

RewriteBase /sub_directory/

Więc chcę coś takiego

RewriteBase /%{current_folder}/

Author: anubhava, 2014-01-11

3 answers

Jest jeden sposób, w jaki można pobrać RewriteBase ze zmiennej środowiskowej, którą można następnie użyć w innych regułach przepisywania:

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

Następnie możesz użyć %{ENV:BASE} w swoich regułach do oznaczenia RewriteBase.

Wyjaśnienie:

Ta reguła działa poprzez porównanie REQUEST_URI ze ścieżką URL, którą widzi RewriteRule, czyli REQUEST_URI z pozbawionym wiodącym RewriteBase. Różnica jest RewriteBase i jest wstawiona do %{ENV:BASE}.

  • W RewriteCond, LHS (test string) może używać back-reference zmienne np. $1, $2 lub %1, %2 etc ale strona RHS tj. condition string nie może używać tych $1, $2 lub %1, %2 zmienne.
  • wewnątrz części warunkowej RHS możemy użyć tylko back-referencji wewnętrznych back-referencji tzn. grup, które przechwyciliśmy w tym warunku. Oznaczane są przez \1, \2 itd.
  • w RewriteCond pierwsza przechwycona grupa to (.*?/). Będzie on reprezentowany przez wewnętrzny back-reference `\1.
  • Jak można zaznaczyć, że zasada ta polega w zasadzie na dynamicznym znajdowaniu RewriteBase przez porównanie %{REQUEST_URI} i $1. Przykładem %{REQUEST_URI} będzie /directory/foobar.php, a przykładem $1 dla tego samego przykładu URI będzie foobar.php. {[30] } umieszcza różnicę w 1. grupie %1 lub \1. W naszym przykładzie zostanie ona wypełniona %1 lub \1 wartością /directory/, która zostanie użyta później przy ustawianiu zmiennej env %{BASE}, tj. E=BASE:%1.
 37
Author: anubhava,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-15 16:04:13

Przyjęte rozwiązanie nie działało dla mnie, myślę, ale to tak: http://www.zeilenwechsel.de/it/articles/8/Using-mod_rewrite-in-.htaccess-files-without-knowing-the-RewriteBase.html

Krótka historia:

RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond $0#%{REQUEST_URI} ([^#]*)#(.*)\1$
RewriteRule ^.*$ %2index.php [QSA,L]
 2
Author: Dakusan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-03 18:52:25

Bazując na anubhava 's answer i Jon Lin' s, Oto co właśnie wymyśliłem dla siebie (nie używałem tego w produkcji ani nie testowałem tego intensywnie jeszcze).

Użyjmy tego przykładowego adresu URL, gdzie .htaccess jest w current_folder:

http://localhost/path_to/current_folder/misc/subdir/file.xyz

Filesystem: /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]

Możesz zobaczyć szczegóły tego, co się dzieje, używając LogLevel alert rewrite:trace6 w swoim httpd.conf w apache, a następnie patrząc w swoim error.log.

Tutaj jest trochę więcej Wyjaśnienie następujących dwóch linijek, które nadal uważam za nieco mylące.

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

Po pierwsze, dwukropek :: nie jest żadnym operatorem; jest tylko arbitralnym ogranicznikiem. RewriteCond rozszerza TestString %{ENV:SUBPATH}::%{REQUEST_URI} do:

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

Wtedy nasz Kondpattern ^(.*)::(.*?)\1$:

  1. ^(.*):: mecze misc/subdir/file.xyz::
  2. \1 jest pierwszą grupą przechwytywania, misc/subdir/file.xyz
  3. (.*?)\1$ staje się (.*?)misc/subdir/file.xyz$
  4. tak więc, nasza druga grupa przechwytywania (.*?) pasuje do pozostałych /path_to/current_folder/

I nasze RewriteRule ustawia CWD na %2, która jest drugą grupą przechwytującą Kondpatterna.

 2
Author: aplum,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-21 18:28:21