Zaawansowane przykłady rozwiązań w mod_rewrite

Korzystanie z wyrażeń regularnych

Potęga funkcjonalności mod_rewrite wiąże się z możliwością tworzenia zaawansowanych wzorców składni. Im bardziej zawiłe przepisanie tym bardziej złożone będzie wyrażenie regularne. Dlatego też, aby w pełni korzystać z możliwości mod_rewrite, musisz opanować korzystanie z wyrażeń regularnych. Poniżej znajdziesz kilka przykładów, które bazują na rozwiniętych wyrażeniach.
RewriteEngine On
RewriteRule ^sklep/([0-9][0-9])/$ sklep.php?id=$1
Pierwszy parametr to nasza maska. Mówi ona o tym, że sprawdzany ciąg znaków zaczyna się od „sklep/” i po nim występują dwie cyfry, np: „sklep/23/„. Okrągłe nawiasy służą do grupowania. Tekst dopasowany w nawiasach może być przekazany jako parametr dla docelowego prostego adresu. Czyli w rezultacie z działania tej reguły nastąpi przepisanie:
sklep/23/ -> sklep.php?id=23

Parę słów rozwinięcia:

  • znaki ^ oraz $ informują o dopasowywaniu od początku do końca tekstu źródłowego. Jeśli je pominiemy,  wyrażenie regularne będzie szukać wystąpienia tekstu w dowolnym miejscu tekstu. Dla przykładu:
    tekst: /produkty/promocja/koszulka/czerwona
    maska:  ^/promocja/$
    wynik: BŁĄD – nie znaleziono szukanej treści. Według naszej maski podany na wejściu tekst powinien zawierać tylko frazę  "/promocja/" i nic więcej.tekst: /produkty/promocja/koszulka/czerwona
    maska: /promocja/
    wynik: SUKCES – w szukanym tekście występuje fraza "/promocja/".
  • [0-9] – oznacza jeden znak z podanego zakresu znaków,
  • (…) – nawiasy te służą grupowaniu. Wartość wyrażenia dopasowania w nawiasach jest przekazywana jako parametr – można ją wypisać używając $1 do $9.

Kolejny przykład:

RewriteEngine On
RewriteRule ^artykul/([a-zA-Z]+)/$ /wyswietl.php?artykul=$1
Jest to bardzo podobny przykład do poprzedniego. Tym razem w masce dopasowania sprawdzamy, czy tekst zaczyna się od frazy „artykul/„, po której spodziewamy się znaleźć tytuł artykułu. W tym celu użyliśmy grupowania zakresu małych i dużych liter. Znak plusa informuje, że może wystąpić jedna lub wiele liter.

Oto przykłady:

tekst: /artykul/MalyTytul/
wynik: /wyswietl.php?artykul=MalyTytul
tekst: /artykul/123/
wynik: błąd dopasowania (tytuł artykułu nie zawiera liter).

Nawiązując do przykładu z pierwszego rozdziału, możemy stworzyć już regułę, która zrealizuje to przepisanie. Przypomnijmy:

RewriteEngine On
RewriteRule ^nowosci/([0-9]+)$ /wyswietl.php?id=$1
Przyjazny link, obsługiwany przez reguły mod_rewrite:
http://moja-strona.home.pl/nowosci/3487
Adres fizyczny (nieprzyjazny), który prowadzi do tej samej zawartości:
http://moja-strona.home.pl/wyswietl.php?id=3487

Dodawanie kończącego znaku slash „/”

Patrząc na te przykłady możesz powiedzieć – wszystko dobrze, tylko co w przypadku, kiedy użytkownik wpisze adres URL bez kończącego go slasha? Mam robić osobne reguły dla każdego przypadku? Nie, nie ma takiej konieczności!

 

Pamiętaj, że po każdym wykonanym przepisaniu strona WWW jest wywoływana ponownie, z nowym adresem URL. I co się z tym wiąże, ponownie są przetwarzane reguły mod_rewrite. Rozbudujmy więc ostatni przykład:
RewriteEngine On
RewriteRule ^artykul/([a-zA-Z]+)$ /artykul/$1/ [R]
RewriteRule ^artykul/([a-zA-Z]+)/$ /wyswietl.php?artykul=$1

Co się stanie po wywołaniu adresu „/artykul/DuzyTytul„?

  1. Zostanie wykonana pierwsza reguła, która zamieni adres na postać „/artyklul/DuzyTytul/” oraz wykona przekierowanie na tą stronę (o tym mówi flaga R).
  2. Nowy adres nie zostanie już dopasowany do pierwszej reguły, więc serwer spróbuje go dopasować do kolejnej reguły – co zakończy się sukcesem.
WAŻNE! Pamiętaj, że niepoprawne reguły powodujące zapętlenia są najczęstszym błędem.

Jak ustrzec się przed zapętleniem reguł?

Przede wszystkim należy pamiętać, że po przepisaniu adresu, następuje ponowne wywołanie strony – już z nowym adresem. Po ponownym załadowaniu strony zostają ponownie wykonane reguły zapisane w pliku .htaccess. Należy więc tak konstruować reguły, aby nie zaszedł przypadek, kiedy raz przepisany adres jest przepisywany ponownie przez tą samą regułę w nieskończoność.

Przykład zapętlającej reguły:

RewriteEngine On
RewriteRule (.*) /pokaz.php/$1
  • Pierwszy przebieg:
    • tekst: artykuly/478
    • wynik: /pokaz.php/artykuly/478
  • Drugi przebieg:
    • tekst: /pokaz.php/artykuly/478
    • wynik: /pokaz.php/pokaz.php/artykul478
Jak widać, reguła ta będzie wykonywać się w nieskończoność. Oto poprawiona wersja, która opiera się na sprawdzeniu, czy przepisywany adres nie zawiera kropki:
RewriteEngine On
RewriteRule  ^([^.]*)$  /pokaz.php/$1
Pierwszy przebieg wygląda podobnie jak w poprzednim przykładzie, natomiast drugi zwróci błąd, gdyż przepisywany tekst zawiera już kropkę. Dlaczego wymuszamy przepisanie tekstu który nie zawiera kropki? W normalnym przypadku kropka pojawia się tylko w nazwie pliku – w tym przypadku jest to „pokaz.php”. Inną metodą jest użycie narzędzia RewriteCond w celu sprawdzenia, czy adres nie zawiera rzeczywistego katalogu i nazwy pliku – jeśli tak, oznacza to, że posiadamy już adres w ostatecznej postaci.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule  (.*) /pokaz.php/$1
Oba dopasowania RewriteCond sprawdzają zawartość wywołanego adresu – pierwsze sprawdza, czy adres nie prowadzi do pliku (parametr -f), natomiast drugie czy nie jest to katalog (parametr -d). Po pierwszym przebiegu i wykonaniu reguły zmienna REQUEST_FILENAME będzie zawierać już nazwę pliku (tj. „pokaz.php”).

Wymuszanie adresu domeny z lub bez przedrostka „www.” lub „http://”

Więcej informacji na ten temat znajdziesz w tym artykule.

Jakie artykuły na temat mod_rewrite znajdę w dokumentacji home.pl?

  • Czy artykuł był pomocny ?
  • Tak   Nie

Dedykowane wsparcie IT i megarabaty!

Pomoc Premium dedykujemy najbardziej wymagającym Klientom home.pl. Powiedz, co możemy dla Ciebie zrobić i oszczędzaj czas.

Poznaj Pomoc Premium Sprawdź ofertę