Mod rewrite

Mod rewrite to moduł serwera Apache umożliwiający transformacje linków do postaci bardziej przyjaznej użytkownikowi i wyszukiwarkom internetowym. Przykładowo strona o adresie:

http://strona.pl/index.php?zmienna=wartosc&zmienna2=inna_wartosc

może być zamieniona linkiem w takiej postaci:

http://strona.pl/index/wartosc/inna_wartosc/

Link taki wygląda czytelniej i jest lepiej indeksowany przez wyszukiwarki.

     1 Pliki .htaccess
     2 Dyrektywa RewriteRule (reguły)
     3 Znaczniki dyrektywy RewriteRule
     4 Dyrektywa RewriteCond (warunki)
     5 Znaczniki dyrektywy RewriteCond
     6 Mod Rewrite Dla serwerów IIs
     7 Linki zewnętrzne:

Pliki .htaccess

Aby korzystać z mod rewrite należy stworzyć w katalogu ze strona plik .htaccess i wpisać do niego polecenie

Options FollowSymLinks
RewriteEngine On

To "włączy" silnik mod rewrite i pozwoli na używanie reguł.

Uwaga: nie wszystkie serwery wirtualne pozwalają na wykorzystywanie plików .htacces.

Ponad to, nawet jeśli masz dostęp do pliku .htaccess to nie koniecznie konfiguracja serwera pozwala na używanie Mod Rewrite.

W takim wypadku silnik Mod Rewrite nie zadziała.</dfn>

Dyrektywa RewriteRule (reguły)

Umieszcza sie je pod instrukcją RewriteEngine On w pliku .htaccess. Opisują one jak mają byc transformowane linki. Składnia jest następująca:

RewriteRule [adres jakiego chcemy używać] [prawdziwy adres pliku] [dodatkowe parametry(znaczniki dyrektywy)]

Najprostrza reguła moze wyglądać tak:

RewriteRule ^index.html$ index.php [L]

Spowoduje ona ze po wpisaniu w przeglądarce adresu do pliku index.html serwer otworzy plik index.php, bez wiedzy odwiedzającego - cała operacja jest niezauważalna. Oczywiście plik index.html nie istnieje, jest to tylko "przezwisko" dla pliku index.php.

Znaki ^ oraz $ przy nazwie pliku to Wyrażenia Regularne (Regular Expression) oznaczające początek ciągu, po którym znajduje się wyraz index.html, zakończony zaraz po literze "l". Reguły tej nie spełniłby wyraz iindex.html albo index.html?id=1.

Wyrażenia regularne pozwalają tworzyć bardziej złożone reguły, np takie w których występują zmienne.

Załóżmy ze na twojej stronie użytkownicy czytają artykuły na stronach:

articles.php?id=1
articles.php?id=2
articles.php?id=3
articles.php?id=4
articles.php?id=5

Takie linki nie wyglądają zbyt dobrze, ale bez sensu było by tworzenie osobnej reguły dla każdej zmiennej (id). W takim przypadku można stworzyć jedną regułę dla wszystkich artykułów, np tak:

RewriteRule ^articles-([^-]+).html$ articles.php?id=$1 [L]

teraz użytkownicy mogą wchodzić na poszczególne pod strony przy pomocy takich linków:

articles-1.html
articles-2.html
articles-3.html
articles-4.html
articles-5.html

Działa to w następujący sposób: wyrażenie regularne ([^-]+) oznacza dowolny ciąg złożony z co najmniej jednego znaku i pozbawiony myślnika. Ciąg taki jest następnie przenoszony na miejsce $1 z drugiej części reguły.

Można używać wielu zmiennych na raz, np:

http://strona.pl/index.php?action=text&mode=edit&tmp=2

Można zamienić na link w postaci:

http://strona.pl/index/text/edit/2/

przy pomocy reguły:

RewriteRule ^index/([^-]+)/([^-]+)/([^-]+)/$ http://strona.pl/index.php?action=$1&mode=$2&tmp=$3 [L]

Znaczniki dyrektywy RewriteRule

*Znacznik [NC] (nocase)
Sprawia, że w danym wzorcu pomijane są różniece w wielkościach znaków. Dla przykładu, dwa poniższe wzorce mają identyczne działanie:
RewriteRule ^([A-Za-z])/?$ web.php?q=$1
RewriteRule ^([a-z])/?$ web.php?q=$1 [NC]
*Znacznik R[=kod] (redirect)
Znacznik ten powoduje formalne przekierowanie wraz z podaniem kodu stanu HTTP, domyślnie powoduje on wysłanie kodu HTTP 302 Moved Temporarily. Przykład:
RewriteRule ^art/(\d+)/?$ art.php?id=$1 [R=301]
Kod w powyższym przykładzie to 301 Moved Permanently.
Używając tego znacznika można zwracać dowolny kod HTTP z zakresu od 300 do 400.
*Znacznik F (forbidden)
Działa podobnie do znacznika redirect, ale od razu wysyła odpowiedź HTTP 403. Jeżeli w ramach jednej reguły znajdzie się ten znacznik oraz redirect, to pierwszeństwa na znacznik forbidden, co oznacza, że zostanie wysłany kod 403 niezależnie od wartości kodu redirect.
*Znacznik G (gone)
Znacznik ten wysyła kod HTTP 410 - Usunięto, który informuje użytkownika o tym, że żądana strona została usunięta. Ma on pierwszeństwo przed znacznikiem redirect, ale ważniejszym od niego jest forbidden.
*Znacznik L (last)
Znacznik ten pozwala na zatrzymanie przetwarzania reguł RewriteRule po skutecznym dopasowaniu adresu URL do reguły.
*Znacznik N (next)
Znacznik next ponownie rozpoczyna proces przepisywania adresu od samego początku listy reguł. W momencie rozpoczęcia ponownego przetwarzania reguł obsługuję one juz nie oryginalny adres URL, ale jego postać przepisano przez wszystkie reguły do momentu pojawienia się znacznika next.
*Znacznik C (chain)
Jeżeli chcielibyśmy traktować blok reguł jako jednostkę, to powinniśmy posłużyć się znacznikiem chain. Wytłumaczmy to na przykładzie:
Rewrite Rule ^art/(\d+)/?$ art.php?id=$1 [C]
RewriteRule ^cat/(\w+)/?$ cat.php?cat=$1 [C]
RewriteRule ^art/[^\d+]/?$ error.php
Jeżeli żadna z reguł związanych znacznikiem chain nie pasuje to przechodzimy do ostaniej.
*Znacznik S=liczba (skip)
Ten znacznik powoduje pominięcie podanej liczby reguł. Znacznik ów zachowuje podobnie się do chain, z tą różnicą, że pozwala pominąć reguły w przypadku udanego dopasowania.
*Znacznik T=typ-mime (type)
W przypadku kiedy chcemy zmienić typ MIME wysyłanego dokumentu, to możemy posłużyć się tym znacznikiem. Na przykład jeżeli mamy pliki xhtml i chcielibyśmy wysłać je za pomocą poprawnego typu MIME (application/xhtml+xml) to możemy wykorzystać tą regułę:
RewriteRule ^.+\.xhtml$ - [T=application/xhtml+xml]
*Znacznik CO=nazwa:wartość:domena[:czaszycia[:sciezka]] (cookie)
Znacznik ten służy do utworzenia ciasteczka w przeglądarce użytkownika . Wymagane są pola nazwa, wartość i domena. Możemy na przykład utworzyć ciasteczko o nazwie bylemtu, istnienie którego będzie oznaczało że użytkownik już odwiedzał naszą stronę.
RewriteRule ^index\.php$ - [CO=bylemtu:true:domena.pl]
*Znacznik E=zmienna:wartosc (env)
Znacznik ten pozwala nadać wartość zmiennej środowiskowej zmienna. W jednej grupie znaczników można przypisać wartości do wielu zmiennych środowiskowych.
*Znacznik QSA (qsappend)
W przypadku obecności tego znacznika mechanizm przepisywania pobierze oryginalny ciąg znaków zapytania i dopisze do niego ciąg znaków wygenerowany przez regułę.
RewriteRule ^index\.php$ index.php?zmienna=wartosc [QSA]
Jeżeli tej regule podamy adres postaci index.php?cos=bla to w wyniku jej działania otrzymamy index.php?zmienna=wartosc&cos=bla.
*Znacznik NE (noescape)
Znacznik ten pomaga unikać automatycznego wyróżniania znaków specjalnych.
*Znacznik PT (passtrough)
Używamy go w momencie kiedy chcemy połączyć moduł mod_rewrite z innymi moduła, które również zajmują się obsługą adresu URL.
*Znacznik NS (nosubreq)
Znacznik ten używamy w momencie jeżeli chcemy aby mechanizm przepisywania adresów pominął regułę, jeżeli żądanie jest wewnętrznym żądaniem podrzędnym. Bardzo rzadko jest używany, jezeli korzystamy z Apache i PHP, przydaje się w momencie dołączenia skryptów CGI.
*Znacznik P (proxy)
Nakazuje on zakończenie przetwarzania reguł i przekazanie danych żądania do modułu mod_proxy.

Dyrektywa RewriteCond (warunki)

Dyrektywa RewriteCond w uproszczeniu spełnia funkcję instrukcji if(), porównuje ciąg znaków z wzorcem lub warunkiem. Jeżeli dane pasują do warunku to wykonywana jest dyrektywa RewriteRule znajdująca się zaraz za RewriteCond. Składnia polecenia:
RewriteCond CiagZnakow WzorzecWarunku [znaczniki dyrektywy]
Przykład(bardzo często stosowany):
RewriteCond %{REQUEST_FILENAME} !-s [NC]
Warunek ten sprawdza czy żądany plik nie jest rzeczywistym plikiem o rozmiarze większym od zera, pomija różnice w wielkości liter.
Najczęstszym sposobem użycia dyrektywy RewriteCond jest porównanie wejściowego ciągu znaków ze wzorcem, podobnie jak z RewriteRule, z tą różnicą, że w tym wypadku mamy dostęp do wielu zmiennych serwera, dlatego wejściowy ciąg znaków może być bardziej rozbudowany.

Zmienne które możemy wykorzystać:
*HTTP_USER_AGENT Ciąg znaków z informacja identyfikującą przeglądarke.
*HTTP_REFERER Dokładnie "polecający", adres strony, która nas skierowała, na konkretną stronę. Nie wszystkie przeglądarki wysyłają, również firewall'e często wycinają to.
*HTTP_COOKIE Ciąg znaków ciasteczka.
*HTTP_FORWARDER Jeżeli żądanie jest obsługiwane przez serwer proxy, to zawiera dowolne przekazywane informacje.
*HTTP_HOST Nazwa komputera wymieniana w rządaniu.
*HTTP_PROXY_CONNECTION Zwraca zawartość nagłówka Proxy-Connection.
*REMOTE_ADDR Adres ip komputera wysłającego żądanie.
*REMOTE_HOST Nazwa komputera wysyłającego żądanie.
*REMOTE_USER Nazwa użytkownika komputera wysyłającego żądanie. Nie musi być podana.
*REMOTE_IDENT Zmienne przeznaczone do celów indentyfikacji. Może zawierać nazwę użytkownika.
*REMOTE_METHOD Metoda żądania pliku (POST lub GET).
*SCRIPT_FILENAME Pełna lokalna ścieżka do żądanego pliku.
*PATH_INFO Dodatkowe informacje o ścieżce.
*QUERY_STRING Ciąg zapytania albo parametry zapytania metodą GET.
*AUTH_TYPE Rodzaj uwierzytelniania.
*DOCUMENT_ROOT Katalog główny strony.
*SERVER_ADMIN Adres email administratora serwera.
*SERVER_ADDR Adres ip lub komputera serwera.
*SERVER_PORT Podany w żądaniu port serwera.
*SERVER_PROTOCOL Nazwa i wersja protokołu żądania.
*SERVER_SOFTWARE Nazwa oprogramowania serwera.
*TIME_YEAR Rok na serwerze.
*TIME_MON Numer miesiąca.
*TIME_DAY Numer dnia.
*TIME_HOUR Godzina żądania.
*TIME_MIN Minuta żądania.
*TIME_SEC Sekunda żądania.
*TIME_WDAY Dzień tygodnia żądania.
*TIME Bierząca godzina.
*API_VERSION Numer wersji interfejsu API serwera Apache.
*THE_REQUEST Pełne żądanie HTTP.
*REQUEST_URI Żądany zasób.
*REQUEST_FILENAME Pełna ścieżka w lokalnym systemie plików do żądanego pliku.
*IS_SUBREQ Informacja, czy żądanie jest wewnętrznym żądaniem podrzędnym.
*HTTPS Wartość on oznacza, że połączenie jest szyfrowane.
Wszystkie zmienne należy umieszczać z procentem przed i w nawiasach klamrowych.

Przykład:
#Jeżeli przeglądarka akceptuje typ MIME application/xhtml+xml to wszystkie pliki wysyła nim
RewriteCond %{HTTP_ACCEPT} application/xhtml+xml
RewriteRule .*.html - [T=application/xhtml+xml

Dyrektywy RewriteCond, można łączyc w grupy. Wpisując kilka instrukcji wpisując jedna pod drugą, łączy się je jak w przypadku użycia AND. Przykład:
RewriteCond %{REQUEST_FILENAME} !-s [NC]
RewriteCond %{REQUEST_FILENAME} !-d [NC]
RewriteRule ^(.+) text.php/$1 [L]

Obydwa pierwsze warunki muszą być spełnione aby wykonane zostało przepisanie z ostaniej linii. Konkretnie w tym wypadku w pierwszej linii jest sprawdzane czy żądany zasób nie jest niepustym plikiem, w drugiej czy przypadkiem nie jest katalogiem. Jeżeli zasób okaże się plikiem lub katalgiem to dyrektywa RewriteRule nie zostanie wykonana.

Używając dyrektywy RewriteCond, możemy nie tylko porównywać ciągi znaków z wyrażeniem regularnym, możemy również kontrolować zmienne systemowe poprzez znaki. W ramach niej możemy używać następujące operatory porównania:
>WzorzecWarunku
<WzorzecWarunku
=WzorzecWarunku

Przeanalizujmy np. taki zapis:
RewriteCond %{TIME_HOUR} <22
RewriteCond %{TIME_HOUR} >7
RerwriteRule .* - [F]

Powoduje on zablokowanie dostępu(zwracanie kodu HTTP 403 - Fobidden) do serwisu, między godzinami 7-22. Oprócz standardowych operatorów, możemy również używac następujących:
*-d sprawdza czy istnieje katalog o nazwie zgodniej z ciągiem znaków.
*-f sprawdza czy istnieje plik o nazwie zgodnej z ciągiem znaków.
*-s działanie jak powyżej z tą różnicą, że plik musi mieć rozmiar większy od zera.
*-l sprawdza czy istnieje dowiązanie symboliczne.
*-F sprawdza czy plik jest dostępny po uwzględnieniu wszystkich restrykcji serwera.
*-U sprawdza czy istnieje adres URL i jest dostępny po uwzględnieniu wszystkich restrykcji serwera.
Jak w językach programowania bywa wstawienie wykrzyknika przed operatorem neguje jego funkcję logiczną. W naszym przypadku neguje wzorzec.

Znaczniki dyrektywy RewriteCond

*Znacznik [NC] (nocase)
Działa tak samo jak w dyrektywie RewriteRule, powoduje pomijanie różnic w wielkościach liter.
*Znacznik [OR] (or)
Jak wiemy, domyślną metodą łączenia dyrektyw RewriteCond jest funkcja logiczna AND, ten znacznik powoduje jej zamianę na OR.

Mod Rewrite Dla serwerów IIs

Mod Rewrite to moduł serwera Apache , jednak jeżeli używasz serwera Microsoft Internet Information Services możesz skorzystać z mod rewrite dzięki wtyczce dostępnej na tej stronie:

http://www.snapfiles.com/get/urlreplacer.html

Linki zewnętrzne:

13 komentarzy

Więcej przykładów można znaleźć na stronie :
http://sf.jogger.pl/2007/05/02/mod-rewrite-w-przykladach/

a także jak stworzyć takie linki w php:
http://sf.jogger.pl/2007/05/19/przyjazne-linki/

sed_dzu: to jest kwestia serwera a nie jezyka programowania, skoro jest Mod Rewrite do IIs to pewnie zadziała z ASP - pozamieniaj w linkach .php na .asp i tyle :)

A ja mam pytanie, czy jest coś takiego dla ASP

Hehe no nie ciekawe, bo transfer siadł :) Ale od kwietnia będą aktualne :P

te artykuły sa na wolnej licencji.. dodajac je tutaj zrzekasz sie autorstwa wiec nie ma znaczenia czy w polu "Ostatni autor" pojawie sie ja czy ty.. wazne zeby artykul byl dobry..

polecam zapoznanie sie z pomocą...

Pomoc

//btw. nie za ciekawe te linki wkleiłes <lol>

Kooba - nie wyśmiewałem się - poprostu dziwiło mnie, że stronę główną może każdy zmienić, przecież tu nawet hackera nie trzeba, żeby zepsuć stronę. A co do edytuj to wiem, ale tylko prosiłem o pozwolenie :) PS: Kooba zedytuj to, żeby było widać, że to Ty jesteś autorem.

BatSk8: widzisz w Template:Main_Site wyśmiewałeś sie z tego systemu a teraz myk, chcesz coś poprawić? ludzie.. nie załamujcie mnie z rana :/

Jasne, że można - klikaj na 'Edycja' i do działa! :)

Marooned powinien być zalążek - mało tego :) Co do tych parametrów to jest to opisane np. tu:
http://www.bilsoftware.com/php-mod_rewrite-1.html

PS: linki zewnętrzne można modyfikować? Coś dodać itp.?

to był zalążek ale jakoś ludzie sie nie palili do rozbudowy wiec przy poprawianiu linkow poprawiłem na zwykły artykuł.. taki spontan, w sumie pochopny..

W ogóle to powinien być zalążek :)
10% treści docelowej

coś o RewriteCond może?

Mnie zawsze ciekawiły [choć czasu nie miałem na szukanie] co oznaczają parametry na końcu, np. [L]