Mod rewrite w przykładach
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¶metr=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
Widzę, że twórczość literacka w zagadnieniu kodu PHP kwitnie. A tutorial tradycyjnie widzę, krótko i na temat.
pozdrawiam
Przy niektórych końcowych przykładach w wyrażeniach przed rozszerzeniem masz nie-escape'owaną kropkę.. warto by pooprawić
Niezwykle przydatne "coś". Tego właśnie szukałem od dłuższego już czasu... Dzięki wielkie!
@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 :)
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łę…
Co do wildcard to musisz jeszcze dodac ze odpowiedni wpis w DNSie musi byc.
jak by to ująć... a to nie od tego jest mod_rewirte cheat sheet? :)
Swietny poradnik! Bardzo mi sie przydal, zwlaszcza przyklad jak przekierowac domena.pl na www.domena.pl. Pozdro!
Bardzo fajne przykłady. Ale może mi ktoś powiedzieć jak w wildcardzie dodać jeszcze po slashu inne zmienne?
Przykład z zamianą bez www na www przekazuje przecież zmienne, a www to przecież subdomena. Czyli to o co pytasz.
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?
Po przepisaniu nie dzialaja odnosniki... Jak zmienic adres hosta przy mod-rewrite?
U mnie to samo , wgrywam plik .htaccess na serwer i znika. mam właczone ukryte pliki. Jest jakis inny sposób na zmiane ?
@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
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łę?
do "lamer" - nie
Możesz użyć odpowiednich formułek, znaleźć regularności ... Najlepiej podaj przykład paru podstron ...
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
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/
Naprawdę piszesz świetne artykuły. Wiesz czego webmasterzy potrzebują najbardziej :P
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
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.
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'.
@GG: słyszałeś o wildcard ? ;)
Dobry artykuły, 5/5 :)
Pozdro
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 :(
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) ;)
dzięki w końcu już wiem jak zrobić przyjazne linki dla mojej witryny, z darmowymi ogłoszeniami.
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)
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]
@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]
Niestety kod
RewriteCond %{HTTP_HOST} !=www.domena.pl
RewriteCond %{HTTP_HOST} ^(www\.)?(.+).domena.pl$
RewriteRule .* ?subdomain=%2
Powoduje wyskoczenie bledu serwera. Przynajmniej mojego Apache'a. Nie wiem jak to dziala z Microsoft-owym IIS-em.
Jest to spowodowane rekurencja, tzn. xxx.domena.pl odczytuje ten xxx i wywoluje xxx.domena.pl/?subdomain=xxx, itd w nieskonczonosc.
Za to forma:
RewriteCond %{HTTP_HOST} !=www.domena.pl
RewriteCond %{HTTP_HOST} ^(www\.)?(.+).domena.pl$
RewriteRule .* http://www.domena.pl/?subdomain=%2
Dziala bez zarzutu.
Idealem dla mnie byloby zostawianie w przegladarce uzytkownika xxx.domena.pl, i rownoczesna automatyczna zamiana na www.domena.pl tylko i wylacznie z punktu widzenia wykonywanego skryptu PHP.
Witam!
Wielkie dzięki za ten manual! Od czterech dni próbowałem spłodzić przekierowanie z subdomeny ale bez skutku. Myślałem, że przeczytałem już cały Internet i chciałem dać za wygraną ale stwierdziłem, że ostatni raz spróbuję. I udało się dzięki Tobie! Piję na Twoje zdrowie. :) Pozdro!
Witam,
a jak zamaskować wychodzący link za pomocą mod_rewrite? A dokładnie chodzi mi o to aby stworzyć takie przekierowanie:
moja_domena.pl/nazwa1 => www.link_zewnetrzny1.pl
moja_domena.pl/nazwa2 => www.link_zewnetrzny2.pl
Witam!
Jak cofnąć regułę
" RewriteRule ^index\.php ./ [R=301,L] "
??
Skasowałem .htaccess i nic nie dało.. nadal daje index.php na /
Dzieki za odp!
Widać nie usunąłeś reguły, albo cache przeglądarki działa.
Usunąłem cały plik .htaccess...
witam
a ja mam taki problem:
chce wywolac watermark.php - wiadomo o co chodzi
ale istniejace pliki maja nazwe np z[1]_999.jpg i tu wszystko sie rozbija o nawiasy
nie moge sobie poradzic z rewriterule zamienić
postac z%5B1%5D_999.jpg na z[1]_999.jpg
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^[%5B\%5D]\.(gif|jpeg|jpg|png)$ watermark.php [QSA,NC]
i pliki sie wyswietlaja ale oczywiscie bez znaku wodnego
pierwsza wersja ktora normalnie dzialala na plikac bez []:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule \.(gif|jpeg|jpg|png)$ watermark.php [QSA,NC]
i bylo dobrze ale teraz jestem zmuszony, tzn tak wyszlo i za duzo zmian by mnie kosztowalo, w kazdym razie teraz pliki mam z [] przy czy wiadomo jest to tablica wywolywana i tresc nawiasow nie ma znaczenia,
powyzszy wpis htacces wywoluje nazwe pliku zamieniajac [ na jego odpowiednik literowy,
nie moge tego przeskoczyc
czy mozna temu zaradzic w htaccess czy musze kombinowac w watemark.php ?
ostatnio męczyłem się z rewrite mod kilka dni bo nie wiedziałem że czasami trzeba określić rodzaj zmiennej jaką wykorzystujemy i zamiast pisać ogólnie ([^-]+) można wskazać że zmiena będzie cyfrą ([0-9]+) bez tego server nie będzie wiedział o co chodzi w likach typu
www.example.com/123/
www.example.com/abc/
Krótko, zwięźle i na temat. Właśnie takiej informacji szukałem od długiego czasu. Super!
Mam taki problem: na stronie umieszczam obiekt flasha, który z określonego katalogu (/slides) podrzędnego (w stosunku do pliku *.SWF) pobiera zdjęcia i je kolejno wyświetla. Dopóki mam adresowanie typu index.php?article=all&page=0, zdjęcia wyświetlają się. W pliku access.log mam wtedy zapis:
GET /slides/i15.jpg (przykładowo).
Wprowadziłam przeadresowanie
RewriteRule ^article/all/([0-9]+)$ index.php?cat=article&name=all&page=$1
i po tym zdjęcia już się nie wyświetlają. W access.log mam:
GET /article/all/0/slides/i15.jpg, a powinno być jak wyżej /slides/i15.jpg.
Jak to ustawić, żeby przy pobieraniu zdjęć nie startował z aktualnego katalogu, tylko z katalogu głównego strony?
Będę wdzięczna za pomoc.
Mam następujący problem.
Chcę aby link domena.pl/hash/232/32j32nsadsda
był tłumaczony na hash.php?id=232&kod=32j32nsadsda
RewriteRule ^hash/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)$ hash.php?id=$1&kod=$2
niestety po wykonaniu w przegladarce
Kod w przeglądarce uprościłem do minimum ...
<?php
$id = $_GET['id'];
$kod = $_GET['kod'];
echo $id;
?>
zmienna nie jest pokazywana (nie jest przekazywana przez GET :/ )
Co zrobić ?
stepien1@gmail.com
Dzięki za pomoc
hej . Mam pytanie . Wcale nie rozumiem o co chodzi z tym rewrite a mam zrobić coś takiego
http://localhost/katalog/index.php?strona=222
na
http://localhost/katalog/222
albo na http://localhost/katalog/222.html (jeżeli sie da)
pomoże ktoś ?
Masz Kolego
http://www.generateit.net/mod-rewrite/
Dzięki... o to mi chodziło. Jesteś wielki!! Dzięki raz jeszcze....
Witam!
od kilku godzin próbuję zamienić:
http://test.loc/index.php?katalog=art na http://art.test.loc
Czy w ogóle można dokonać takiej zamiany?
Z góry dziękuję za pomoc
Bardzo przydatny zbiór informacji. Część przedstawionych regułek stosuję na swoich stronach (np. przekierowanie 301). Ale kilku nie znałem, a widzę, że mogą być przydatne.
Chcę traktować podstronę witryny jak subdomenę. Przypisałem na serwerze redirecting aby adres subdomeny kierował do tej podstrony. Ale nie wiem jak zrobić aby podstrona wyświetlała się z adresem subdomeny a nie własnym.
subdomena: swietlica.mojadomena.pl
podstrona: mojadomena.pl/kategorie/12/swietlica
Słyszałem że można to przypisać w httacces ale w tej ilości przykładów gubię się. Czy ktoś mi to rozpisze ?
Bardzo ciekawy artykuł, ale mam pytanie, jeśli mam adres:
www.nazwastrony.pl/galeria/gal.php?dzial=1&galeria=1
będę chciał zrobić aby adres wyglądał tak: www.nazwastrony.pl/galeria/1/1/
problem tkwi w tym czy da się zablokować aby po wejściu na www.nazwastrony.pl/galeria/gal.php?dzial=1&galeria=1 nie była ta strona widoczna??
Nigdzie nie mogę znaleźć jak w takim wyłączonym katalogu włączyć ponowne zwykłe wyświetlanie stron.
No to pytanie za sto punktów. leży sobie plik /alamakota.txt (w DocumentRoot lub ~/public_html). Chciałbym aby było dostępny jako /teksty/alamakota i niedostępny jako /alamakota.txt
Hmm... zawsze można się posłużyć generatorami wyrażeń typu http://www.generateit.net/mod-rewrite/ . Ale dzięki za info :)
Mała poprawka potrzebna:
RewriteRule !\.(js|ico|gif|jpg|png|css)$ - [L]
RewriteRule (.*) index.php?a=$1
Usuń negację (!) z 1. linijki, bo działa odwrotnie niż powinno.
Ale ogólnie i tak dzięki za tą formułkę. Przyda się.
Panowie potrzebuję pomocy.
Adresy często posiadam w formie odwroconego slasha (przed index):
/aa6078504/a574d6846\index.xml
Jak wykonać rewrite_mode dla wszystkich adresów, które mają błędny adres z odwóronym slashem? Nie może się ta reguła odnosić jedynie do index.xml a do innych stron.
Z góry dzięki!!!
Nowy komentarz