Z pogranicza

Mod rewrite

  • 2008-02-05 23:54
  • 14 komentarzy
  • 17994 odsłony
  • Oceń ten tekst jako pierwszy
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.

Spis treści

          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.


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ą adresó 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>
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:


14 komentarzy

Brak avatara
Krzysiek 2014-04-01 08:46

Do operatorów typu -s, -d,... nie daje się znacznika NC, który stosuje się tylko do wyrażeń regularnych. Strasznie się przez to logi syfią...

stormfly 2007-08-02 14:54

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/

Kooba 2006-04-08 12:49

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 :)

sed_dzu 2006-04-08 12:21

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

BatSk8 2006-03-26 20:37

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

Kooba 2006-03-26 19:05

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>

BatSk8 2006-03-26 17:43

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.

Kooba 2006-03-26 11:03

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

Marooned 2006-03-26 01:58

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

BatSk8 2006-03-25 16:14

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.?

Kooba 2006-03-25 15:39

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..

Marooned 2006-03-23 21:30

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

SebaZ 2006-03-23 20:12

coś o RewriteCond może?

Marooned 2006-03-23 19:12

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