» Mod rewrite w przykładach

2007-05-02 22:06

Postanowiłem zebrać i opisać kilka przydatnych rozwiązań dotyczących mod rewrite. Mam nadzieję, że ten wpis ułatwi poszukiwania odpowiednich regułek.

Włączenie mod_rewrite i ustawienie domyślnej ściężki.

RewriteEngine On
RewriteBase /

# na lokalnym komputerze w linuxie często spotykamy

RewriteBase /~nazwa_uzytkownika/katalog_ze_strona/

Rozpoznanie subdomen ustawionych na stronę główną, tzw. wildcard (jeśli wyświetla nam się 404 - brak strony, sprawdźmy czy subdomena kieruje na stronę główną). Do zmiennej subdomain przekazujemy nazwę subdomeny. Bardzo często zamiast tego odczytuje się tą domenę w php poprzez $_SERVER['HTTP_HOST'].

RewriteCond %{HTTP_HOST} !=www.domena.pl
RewriteCond %{HTTP_HOST} ^(www\.)?(.+).domena.pl$
RewriteRule .* ?subdomain=%2

Drugi przykład z subdomenami przekierowuje na plik o nazwie subdomeny.

RewriteCond %{HTTP_HOST} !=www.domena.pl
RewriteCond %{HTTP_HOST} ^(.*).domena.pl$
RewriteRule .* %1.php

Przekierowanie 301, aby google widziało wszystkie nasze strony pod www.domena.pl, a nie część pod domena.pl, a część pod www.domena.pl. Dodatkowo zwiększa PR poprzez sumowanie odwołań do obu adresów.

RewriteCond %{HTTP_HOST} ^przyklad.pl
RewriteRule (.*) http://www.przyklad.pl/$1 [R=301,L]

Przekierujemy starą stronę na nową.

RewriteCond %{HTTP_HOST} ^www.stara-strona.pl [or]
RewriteCond %{HTTP_HOST} ^stara-strona.pl
RewriteRule (.*) http://www.nowa-strona.pl/$1 [R=301,L]

Można też to zrobić za pomocą php wstawiając do każdego skryptu odpowiedni kod.

Przekierowanie z index.php na ./.

RewriteRule ^index\.php ./ [R=301,L]

Kilka przykładów uruchomienia akcji dokument z jego indentyfikatorem id. Cyfry z poprzedzającym znakiem dolara odpowiadają kolejnym nawiasom.

# www.przyklad.pl/tytul-artykulu,d20.html
# tytuły złożone z małych liter, cyfr, myślnika i podkreślenia

RewriteRule ^[a-z0-9\-\_]+,d([0-9]+)\.html$ ?a=dokument&id=$1

# www.przyklad.pl/dokument/tytul-artykulu/20/
# akceptuje ze slashem i bez na końcu

RewriteRule ^dokument/(.+)/([0-9]+)/?$ index.php?a=dokument&id=$2

# www.przyklad.pl/dokument/tytul-artykulu/20/
# akceptuje tylko ze slashem na końcu

RewriteRule ^dokument/(.+)/([0-9]+)/$ artykuly.php?a=dokument&id=$2

# www.przyklad.pl/dokument,tytul-artykulu,20.html

RewriteRule ^dokument,(.+),([0-9]+)\.html$ index.php?a=dokument&id=$2

Czasem zdarza się, że dwa linki spełniają kryterium, należy wtedy użyć [L], które powoduje, że dalej nie sprawdza w aktualnym RewriteCond. Ważna jest kolejność, gdybyśmy napisali nasz przykład na odwrót zawsze wykonywałby się pierwszy przypadek.

RewriteRule ^(.+),(.+)\.html$ index.php?a=$1&id=$2 [L]
RewriteRule ^(.+)\.html$ index.php?a=$1 [L]

Można zabezpieczyć by odwołania do plików, które istnieją nie podlegały regułom mod rewrite. W narzym przypadku jeśli plik nie istnieje to otwórz stronę główną.

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteuRule .* index.php [L]

Regułka mod rewrite blokująca pliki z roszerzeniem .tpl oraz .tpl.php.

RewriteCond %{REQUEST_URI} \.(tpl|tpl.php)$ 
RewriteRule .* - [F]

Przekieruj wszystkie odwołania do zmiennej a, poza plikami z rozszerzeniami podanymi w nawiasie.

RewriteRule !\.(js|ico|gif|jpg|png|css)$ - [L]
RewriteRule (.*) index.php?a=$1

Można to wykonać też w inny sposób i wtedy odwoływać się do adresu poprzez $_SERVER['REQUEST_URI'], a nie zmienną a jak w poprzednim przykładzie.

RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php

Czasami potrzebne jest doczepienie całego zapytania query string. Służy do tego flaga QSA.

# przy wywołaniu test.html?parametr=2
# zostanie uruchomiony index.php?a=$1&parametr=2

RewriteRule ^(.*).html$ index.php?a=$1 [QSA]

Mam nadzieję, że po tym artykule dla każdego mod rewrite stanie się prostsze.

Słowa kluczowe: Apache, Linux, Techblog, google, mod_rewrite, przyjazne linki, seo, artykuł, blog

Komentarze i opinie

vj_
2007-05-02 22:29

Widzę, że twórczość literacka w zagadnieniu kodu PHP kwitnie. A tutorial tradycyjnie widzę, krótko i na temat.

pozdrawiam

BoskiDialer
2007-05-03 00:22

Przy niektórych końcowych przykładach w wyrażeniach przed rozszerzeniem masz nie-escape'owaną kropkę.. warto by pooprawić

2007-05-03 01:40

Niezwykle przydatne "coś". Tego właśnie szukałem od dłuższego już czasu... Dzięki wielkie!

sf
2007-05-03 08:30

@BoskiDialer: tak wiem o tym i się zastanawiałem czy tego nie poprawić, ale tak naprawdę doszedłem do wniosku, że jeśli będzie wstawione coś innego zamiast tej kropki to ktoś w ogóle nie wejdzie na tą stronę, a tak jest troszkę większa czytelność

hm, ale w sumie jak teraz patrze to w dwóch miejscach przydałoby się dodać tego slasha :)

Michał Górny
2007-05-03 10:01

Tylko tak chciałbym zwrócić uwagę, że postęp idzie raczej w kierunku usuwania www. z adresów, nie w ich doklejanie na siłę…

2007-05-04 18:45

Co do wildcard to musisz jeszcze dodac ze odpowiedni wpis w DNSie musi byc.

GiM
2007-05-08 11:48

jak by to ująć... a to nie od tego jest mod_rewirte cheat sheet? :)

AGD
2007-05-08 20:43

Swietny poradnik! Bardzo mi sie przydal, zwlaszcza przyklad jak przekierowac domena.pl na www.domena.pl. Pozdro!

yasiek
2007-07-16 18:35

Bardzo fajne przykłady. Ale może mi ktoś powiedzieć jak w wildcardzie dodać jeszcze po slashu inne zmienne?

2007-07-16 18:45

Przykład z zamianą bez www na www przekazuje przecież zmienne, a www to przecież subdomena. Czyli to o co pytasz.

yasiek
2007-07-17 00:25

Hm... no tak, ale tutaj przenosi po prostu na wersję adresu z www... a co zrobić żeby adres został dla przykładu taki:
www.subdomena.domena.pl/id=1&strona=3
a zmienne id=1 i strona=3 były odpowiednio przekazane do skryptu?

lukasz
2007-12-22 09:01

Po przepisaniu nie dzialaja odnosniki... Jak zmienic adres hosta przy mod-rewrite?

2008-05-08 13:48

U mnie to samo , wgrywam plik .htaccess na serwer i znika. mam właczone ukryte pliki. Jest jakis inny sposób na zmiane ?

2008-05-08 13:52

@legowiska: na jakim serwerze? za mało danych podajecie by cokolwiek poradzić ;) możliwe, że po prostu serwer wyrzuca Wam te pliki (zwłaszcza na darmowych serwerach, najlepiej wysłać e-mail do administracji czy te pliki są dozwolone), a jak nie to po prostu spróbować innego klienta ftp

Lamer
2008-05-24 20:58

Dzięki za przykłady!

A jak powinien wyglądać .htaccess, gdy chcę przekierować całą witrynę zrobioną w *html na nową wersję w *php?
Dla każdej strony muszę napisać regułę?

2008-06-19 22:05

do "lamer" - nie

Możesz użyć odpowiednich formułek, znaleźć regularności ... Najlepiej podaj przykład paru podstron ...

elektryk
2008-07-11 13:41

Z tych regułek już zaczynam korzystać.
Mam jeszcze pytanie, jak zrobić na swojej stronie tzw. "przyjazne linki"?

Jak z takiego linku wyciągnąć zmienną id z bazy MySQL?

np. www.example.com/artykuly/przyjazny-artykul.php => www.example.com/artykul.php?id=666

sf
2008-07-11 13:44

nie da się bezpośrednio, musisz mieć dodatkową kolumnę, która będzie przechowywać 'przyjazny-artykul' zobacz na mój ostatni komentarz tutaj :

http://sf.jogger.pl/2007/05/19/przyjazne-linki/

2008-07-17 18:53

Naprawdę piszesz świetne artykuły. Wiesz czego webmasterzy potrzebują najbardziej :P

Driver
2008-08-06 13:05

a jak zmienić takie zachowanie:
subdomena.domena.pl -> domena.pl/subdomena
www.subdomena.domena.pl -> domena.pl/subdomena
na takie:
subdomena.domena.pl -> subdomena.domena.pl
www.subdomena.domena.pl -> subdomena.domena.pl

2008-10-24 09:21

Bardzo przyjazny art. oby takich więcej :).
Mi przydał się akurat najbardziej przykład z www, tego szukałem, bo tak jest zamęt i google indeksuje nie to co ma.

GG
2009-02-04 22:01

Do Nobleman i Driver:
subdomena.domena.pl to adres w DNSie...wątpie żeby komuś się chciało robić tysiące wpisów DNS dla przykładowej strony z tysiacem artykułów... Zwykle żaden hosting nie pozwoli na dodanie tylu mulących wpisów. Dwa - na pozycjonowaniu w googlu daleko nie zajedziecie na tym...
Jak chodzi o www.domena.pl -> domena.pl to najprosciej w PHP robisz ereg'a czy REQUEST_URI ma w adresie 'www', Jeśli ma to dajesz header(Location) na URI bez 'www'.

sf
2009-02-04 22:04

@GG: słyszałeś o wildcard ? ;)

Gość
2009-02-05 10:46

Dobry artykuły, 5/5 :)
Pozdro

Dorotka
2009-04-25 20:16

Witam,

fajne przykłady ale to nadal zbyt skomplikowane dla takiej osoby jak ja :(
czy ktoś mógłby pomóc?

jak napisać przekierunkowanie dla

www.mojastrona.com/strona.php?i=1 na www.mojastrona.com/dobry

a druga

www.mojastrona.com/strona.php?i=2 na www.mojastrona.com/niedobry

Pomocy :(

Maciek
2009-04-28 19:12

Najlepiej to chyba:
RewriteRule ^dobry/?$ strona.php?i=1
RewriteRule ^niedobry/?$ strona.php?i=2

Oczywiście pod warunkiem, że masz Mod rewrite włączony na serwerze i wykonałeś pierwsze kroki (wpis do pliku .htaccess) ;)

2009-06-09 21:03

dzięki w końcu już wiem jak zrobić przyjazne linki dla mojej witryny, z darmowymi ogłoszeniami.

2009-07-31 11:30

moim zdaniem przekierowanie w .htaccess powinno być na index.php, reszte powinien robić php żeby nie obciążać apache (oczywiście php powinno działać jako fcgi)

Przemek
2010-01-19 23:42

Nie działa : ( pomożecie?
Nie wiem gdzie popełniam błąd, ze dwadzieścia razy zmieniałem ten wpis...

RewriteEngine On

RewriteCond %{HTTP_HOST} ^www.mojastrona.waw.pl/info.html [or]
RewriteCond %{HTTP_HOST} ^mojastrona.waw.pl/info.html
RewriteRule (.*) http://www.mojastrona.waw.pl/nowe_info.html/$1 [R=301,L]

2010-02-01 14:36

@Przemek

RewriteEngine On

RewriteCond %{HTTP_HOST} ^www\.mojastrona\.waw\.pl$ [OR]
RewriteCond %{HTTP_HOST} ^mojastrona\.waw\.pl$
RewriteRule ^/info\.html(.*)$ http://www.mojastrona.waw.pl/nowe_info.html/$1 [R=301,L]

A może prościej:
RewriteEngine On
RewriteRule ^/info\.html$ /nowe_info.html [R=301,QSA,L]

Nowy komentarz

 
 
Projektowanie i tworzenie stron www. Opisy i recenzje oprogramowania typu cms, blog, wiki, open source.
Wszelkie prawa zastrzeżone.