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}/
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ędziefoobar.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
.
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]
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$
:
-
^(.*)::
meczemisc/subdir/file.xyz::
-
\1
jest pierwszą grupą przechwytywania,misc/subdir/file.xyz
-
(.*?)\1$
staje się(.*?)misc/subdir/file.xyz$
- 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.
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