Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]Plik .htaccess - problem z przepisaniem adresu
Forum PHP.pl > Forum > Przedszkole
qrzysztof
W pliku .htaccess mam komendę:

Kod
RewriteRule ^([^/\.]+)/?$ home.php?profil=$1 [L]


która przepisuje mi adresy typu www.domena.pl/blabla na www.domena.pl/home.php?profil=blabla.

Wszystko działa świetnie, jest jednak mały teoretyczny problem.

W folderze, na który wskazuje domena główna mam kilka katalogów. Przechowywane są w nich pliki .php i .js. Te pliki nie powinny być dostępne z poziomu przeglądarki i nie są (ustalone
Kod
deny from all
dla danych rozszerzeń).

Problem polega na czymś inny. Jeśli mam na przykład katalog newsy a zarejestruje się użytkownik z nazwą newsy (zawsze możliwe) to po wpisaniu

www.domena.pl/newsy

nie przepisuje na

www.domena.pl/home.php?profil=newsy

ale zamiast tego na

www.domena.pl/newsy/?profil=newsy

Mogę zastrzec nazwy użytkownika, które są identyczne z katalogami ale to mało elastyczne rozwiązanie i nie do końca rozwiązuje problem bo mimo braku użytkownika newsy i tak www.domena.pl/newsy będzie źle przepisywane. Najlepsze byłoby rozwiązanie problemu na poziomie .htaccess.
erix
Cytat
Problem polega na czymś inny. Jeśli mam na przykład katalog newsy a zarejestruje się użytkownik z nazwą newsy (zawsze możliwe) to po wpisaniu

Nie da się tego obejść. Katalog ma wyższy priorytet od reguł przepisywania.
qrzysztof
A da się przynajmniej zrobić tak żeby

www.domena.pl/blabla/

przerzucało mnie na

www.domena.pl/blabla

gdy katalog blabla nie istnieje?


Teoretycznie moja reguła powinna brać ze slashem lub bez. Ale jak jest ze slashem to widzę w logach, że szuka w katalogu blabla (którego nie ma).
erix
Pokaż lepiej cały swój htaccess.
qrzysztof
Kod
Options ALL -Indexes

<FilesMatch "^(class\.)">
deny from all
</FilesMatch>

<Files *.inc>
deny from all
</Files>

ErrorDocument 401 /errordoc/error.php
ErrorDocument 403 /errordoc/error.php
ErrorDocument 404 /errordoc/error.php
ErrorDocument 500 /errordoc/error.php

Options FollowSymLinks
RewriteEngine On
RewriteRule ^([^/\.]+)/?$ home.php?profil=$1 [L]
erix
Cytat
Teoretycznie moja reguła powinna brać ze slashem lub bez

Na pewno? Ja widzę co innego:
[APACHE] pobierz, plaintext
  1. RewriteRule ^([^|||/|||\.]+)/?$ home.php?profil=$1 [L]
[APACHE] pobierz, plaintext

Kluczową część wziąłem między |.
qrzysztof
Nie za bardzo rozumiem, ale guru wyrażeń regularnych nie jestem, więc może robię gdzieś błąd.

[APACHE] pobierz, plaintext
  1. RewriteRule ^([^/\.]+)/?$ home.php?profil=$1 [L]
[APACHE] pobierz, plaintext


W tej regule miałem na myśli ten drugi slash (/). Jest po nim znak zapytania więc jest opcjonalny (występuje raz albo wcale). Ten pierwszy występuje w nawiasie kwadratowym, który miał symbolizować dowolny zestaw znaków z pominięciem slasha (/) i znaku kropki (.).

Oba wywołania:

www.domena.pl/blabla

i

www.domena.pl/blabla/

łapią się na tę regułę. Problem tylko w tym, że drugie nie przepisuje adresu w oczekiwany przeze mnie sposób.
erix
Ech, inaczej: masz katalog o takiej nazwie?

Cytat
Problem tylko w tym, że drugie nie przepisuje adresu w oczekiwany przeze mnie sposób.

Czyli co się dzieje?
qrzysztof
Nie mam katalogu blabla.

Żądanie:

www.domena.pl/blabla

jest obsługiwane zgodnie z oczekiwaniami, czyli zamieniane na:

www.domena.pl/home.php?profil=blabla

Natomiast żądanie:

www.domena.pl/blabla/

powoduje, że rewrite przed wszystkimi operacjami wykonuje jeszcze:

[APACHE] pobierz, plaintext
  1. add path info postfix: www.domena.pl/blabla -> www.domena.pl/blabla/
[APACHE] pobierz, plaintext


Samo zastosowanie reguły w logu jest prawidłowe. Natomiast powyższa operacja powoduje, że wszystkie obrazki (umieszczone w /images/) oraz plik (main.css umieszczony w katalogu głównym) zamiast być szukane w odpowiednio:

/images/
/main.css

są szukane w:

/blabla/images/
/blabla/main.css

To powoduje, że po wpisaniu www.domena.pl/blabla/ zawartość strony z profilem się wyświetla, ale nie ma obrazków ani stylów.
phpion
Bo pewnie ścieżki do obrazków/stylów masz zapisane jako względne (czyli np. style.css). Zapisz je jako bezwzględne czyli rozpoczynając od / (np. /style.css). Powyższe zadziała jeśli projekt odpalasz jako np. http://localhost/. Jeśli jest to http://localhost/projekt/ to zamiast / musisz podać /projekt/
toel
j.w. ew. jeśli strona znajduje się w jakimś podkatalogu a nie w głównym katalogu serwera to http://www.w3schools.com/TAGS/tag_base.asp
qrzysztof
Dzięki, to rozwiązało więcej problemów niż się spodziewałem. Obecnie zarówno:

1) www.domena.pl/nazywamsiekatalog

jak i

2) www.domena.pl/nazywamsiekatalog/

wyświetlają poprawnie stronę z profilem (nazywamsiekatalog nazwa użytkownika ale również katalog istniejący w katalogu głównym). Jedyna drobna niedogodność jest taka, że w tym pierwszym przypadku adres w pasku zmienia się na:

www.domena.pl/nazywamsiekatalog/?profil=nazywamsiekatalog

Będę z tym dalej walczył. No chyba, że ktoś ma jakiś pomysł.
toel
RewriteBase w htaccess ustaw
qrzysztof
Nadal z tym walczę.

Obecnie nie rozumiem zachowania reguły:

Kod
RedirectMatch ^/projekt/([^/\.]+)/$ http://localhost/projekt/przekierujmniegdzies/$1


Wzorzec wyraźnie określa, że ma "łapać" tylko to co jest zakończone slashem. I tak jest o ile żądane URI nie pokrywa się z istniejącym katalogiem. Czyli 2 przypadki:

1) w katalogu głównym nie ma katalogu blabla

a-) http://localhost/projekt/blabla nie przekierowuje (zachowanie pożądane - bo nie ma slasha na końcu)
b-) http://localhost/projekt/blabla/ przekierowuje (zachowanie pożądane - jest slash na końcu)

2) w katalogu głównym istnieje katalog blabla

a-) http://localhost/projekt/blabla przekierowuje (zachowanie niepożądane - nie ma slasha na końcu więc dlaczego przekierowuje?)
b-) http://localhost/projekt/blabla/ przekierowuje (zachowanie pożądane - jest slash na końcu)

Problematyczna jest zatem tylko sytuacja 2a). Rozumiem, że jeśli istnieje katalog blabla to żądane URI zostaje gdzieś niejawnie przepisane z blabla na blabla/ i wtedy "łapie" się na moją regułę. Da się temu jakoś zaradzić?
erix
Cytat
Problematyczna jest zatem tylko sytuacja 2a). Rozumiem, że jeśli istnieje katalog blabla to żądane URI zostaje gdzieś niejawnie przepisane z blabla na blabla/ i wtedy "łapie" się na moją regułę. Da się temu jakoś zaradzić?

Czytanie ze zrozumieniem jest w tej chwili na poziomie doktoratu?

http://forum.php.pl/index.php?showtopic=16...st&p=795521
qrzysztof
Nigdzie nie pisałem, że mam magistra guitar.gif

Cytat(erix @ 5.10.2010, 11:39:32 ) *
Nie da się tego obejść.


Być może rozwiązać wspomnianego problemu się nie da (choć dla mnie to wątpliwe) ale obejść na pewno się da i to na wiele różnych sposobów. Ja swój zaprezentuję poniżej, gwoli zakończenia tematu.

Wszystkie żądania nie będące katalogami i kończące się slashem zamieniamy na to samo bez slasha.
[APACHE] pobierz, plaintext
  1. RewriteCond %{REQUEST_FILENAME} !-d
  2. RewriteRule ^([^/\.]+)/$ /$1 [R=301]
[APACHE] pobierz, plaintext


Żądania będące katalogami i nie kończące się slashem zamieniamy na to samo ze slashem.
[APACHE] pobierz, plaintext
  1. RewriteCond %{REQUEST_FILENAME} -d
  2. RewriteRule ^([^/\.]+)$ /$1/
[APACHE] pobierz, plaintext


Na koniec wystarczy odpowiednia reguła przepisująca:
[APACHE] pobierz, plaintext
  1. RewriteRule ^([^/\.]+)/?$ home.php?profil=$1 [L]
[APACHE] pobierz, plaintext


Teraz każdy profil (niezależnie czy koliduje z katalogiem) jest osiągalny za pomocą

www.domena.pl/nazwa

oraz

www.domena.pl/nazwa/

Z tym że profile kolidujące z katalogami mają domyślnie slash na końcu (jeśli nie to przekierowanie), a profile niekolidujące domyślnie slasha na końcu nie mają (jeśli tak to przekierowanie). W ten sposób do żadnego profilu nie ma dwóch adresów (Google zadowolone) a każdy jest osiągalny na dwa dostępne sposoby. Jedyna różnica między profilami kolidującymi a niekolidującymi to slash na końcu. Dosyć subtelna, a zatem obejście satysfakcjonuje mnie w 100%.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.