Mod_rewrite pro hezká URL – RewriteCond

29. července 2005

V tomto článku si ukážeme velice užitečný příklad RewriteCond pro automatické přesměrování na „www“ verzi stránek nebo také pro zamezení prohlížení obrázků z cizích serverů. RewriteCond má ale mnohem více možností, například přesměrování v závislosti na aktuálním čase…

Z hlediska SEO je velice důležité zachovávat jednotný tvar URL, a proto je dobré si hned na začátku ujasnit, zda budete používat URL s nebo bez „www“. Potom můžeme pomocí HTTP protokolu přesměrovat návštěvníka na správnou verzi stránek. Samozřejmě, k přesměrování na „www“ verzi se opět dají využít funkce v PHP, s mod_rewrite se dá ale dosáhnout stejného efektu velice jednoduše.

Pokud tedy návštěvník zadá adresu http://example.com/nasefirma.html, bude přesměrován na http://www.example.com/nasefirma.html:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^example.com
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,QSA]
RewriteCond %{HTTP_HOST} ^www.example.com
RewriteRule ^(.*).html$ %{DOCUMENT_ROOT}/index.php?stranka=$1 [L,QSA]

V tomto příkladu jste si jistě všimli nového příkazu RewriteCond:

RewriteCond      testovaný řetězec      výraz

Je to vlastně porovnávací příkaz, který vyhodnotí název proměnné (v tomto případě serverovou HTTP_HOST) s vlastní hodnotou. Tento příkaz se váže jen na jedno následující RewriteRule, které je vykonáno v případě platnosti podmínky.

V tomto případě nejdříve zjišťujeme, zda k nám návštěvník přišel s adresou postrádající prefix „www“. Pokud tomu tak je, přesměrujeme ho na stejnou adresu s „www“ na začátku zasláním hlavičky HTTP/1.1 301 Moved Permanently, kterou obstarává parametr R=301. Všimněte si, že toto pravidlo není konečné (není L), protože jsme jenom upravili adresu na „www“ verzi a v dalším pravidle s ní ještě budeme pracovat.

V následujícím kroku opět použijeme RewriteCond pro specifikování pravidla z předchozího příkladu jen na „www“ varianty. Toto pravidlo už konečné je.

V tomto příkazu, ale i v jiných, můžeme využívat kromě proměnné HTTP_HOST také další:

HTTP proměnné
HTTP_USER_AGENT, HTTP_REFERER, HTTP_COOKIE, HTTP_FORWARDED, HTTP_HOST, HTTP_PROXY_CONNECTION, HTTP_ACCEPT
connection a request proměnné
REMOTE_ADDR, REMOTE_HOST, REMOTE_USER, REMOTE_IDENT, REQUEST_METHOD, SCRIPT_FILENAME, PATH_INFO, QUERY_STRING, AUTH_TYPE
interní serverové proměnné
DOCUMENT_ROOT, SERVER_ADMIN, SERVER_NAME, SERVER_ADDR, SERVER_PORT, SERVER_PROTOCOL, SERVER_SOFTWARE
systémové proměnné
TIME_YEAR, TIME_MON, TIME_DAY, TIME_HOUR, TIME_MIN, TIME_SEC, TIME_WDAY, TIME
speciální mod_rewrite hodnoty
API_VERSION, THE_REQUEST, REQUEST_URI,REQUEST_FILENAME, IS_SUBREQ

Přesměrování na verzi stránek bez „www“

Pokud chcete úplně opačný efekt, tedy přesměrovat na verzi bez „www“, stačí jen přehodit pravidla RewriteCond. Bude to tedy vypadat takto:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www.example.com
RewriteRule ^(.*)$ http://example.com/$1 [R=301,QSA]
RewriteCond %{HTTP_HOST} ^example.com
RewriteRule ^(.*).html$ %{DOCUMENT_ROOT}/index.php?stranka=$1 [L,QSA]

Různé verze prohlížečů, různé stránky

V současnosti už jde o hodně archaický příklad, můžeme si však na něm ukázat méně používané využití mod_rewrite. A navíc trochu rozšíříme znalosti RewriteCond.

RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} ^.*Firefox.* [OR]
RewriteCond %{HTTP_USER_AGENT} ^.*Opera.*
RewriteRule ^(.*).html$ %{DOCUMENT_ROOT}/index.php?action=$1&prohlizec=firefox-opera [L,QSA]
RewriteRule ^(.*).html$ %{DOCUMENT_ROOT}/index.php?action=$1&prohlizec=jiny [L,QSA]

Příkazy RewriteCond se dají kombinovat mezi sebou pomocí logického součinu a součtu. Přičemž, pokud za sebou umístíme více RewriteCond, defaultně se použije AND. Pokud chceme využít služeb logického součtu, musíme mezi ně umístit výraz [OR]. Bez použití OR bychom museli napsat o jeden řádek kódu více – úplně stejné RewriteRule s jiným RewriteCond.

Identifikace browseru se nachází v serverové proměnné HTTP_USER_AGENT. Více o těchto hlavičkách si můžete přečíst třeba v článku Statistika přístupů v PHP – detekce prohlížeče, my se zde omezujeme jen na demonstrační příklad – pokud hlavička obsahuje výraz Opera nebo Firefox, přesměrujeme na nějakou stránku. Jakákoli jiná hlavička, která neodpovídá pravidlům v RewriteCond, způsobí přesměrování na index.php s parametrem prohlizec=jiny.

Zamezení linkování obrázků z cizích serverů

I na toto se dá velice jednoduše mod_rewrite využít. V principu jde pouze o to, že zkontrolujeme, zda požadavek přišel z nějakého cizího serveru, a v případě, že požaduje obrázek, podstrčíme mu nějaký jiný. Třeba prázdný…

Takto snadno zabráníte používání svých obrázků na cizích stránkách a nikdo vám nebude zvyšovat traffic.

RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://example.com.*$
RewriteCond %{HTTP_REFERER} !^http://www.example.com.*$
RewriteRule .*.(gif|jpg|jpeg|png|GIF|JPG|JPEG|PNG)$ http://www.example.com/bad.gif [L,R]

Tentokrát jsme spojili tři RewriteCond pomocí výchozího logického součinu. Musíme zkontrolovat, zda serverová proměnná, uchovávající odkud návštěvník přišel (HTTP_REFERER) neobsahuje jednak prázdnou hodnotu (nepřišel odnikud – je na první stránce našeho webu nebo se jedná o přímý přístup), nebo neobsahuje přímo adresu vašeho webu, ať už s „www“ či bez (v případě, že uživatel prochází vaším webem). Všimněte si vykřičníku před regulárním výrazem, který znamená negaci.

Pokud tyto podmínky vyhovují a uživatel žádá soubor s příslušnou koncovkou pro obrázek, přesměrujeme ho na jiný obrázek, ve kterém mu můžeme efektně sdělit, že má smůlu.

Přesměrování v závislosti na čase

Sice asi trochu vyumělkovaný příklad, ale aspoň si rozšíříme znalosti příkazu RewriteCond. Můžeme zde používat samozřejmě i logické operátory, případně i další výrazy, pomocí kterých zjistíme, zda soubor skutečně existuje, zda se jedná o složku a podobně (úplný seznam najdete v nápovědě k příkazu RewriteCond).

My si však ukážeme, jak nabídnout uživateli dvě různé stránky v závislosti na čase. Může to být třeba i nějaká stránka ukazující na pracovní dobu zaměstnanců, i když toto opět dá s výhodou řešit přímo v PHP.

RewriteEngine On
RewriteCond %{TIME_HOUR}%{TIME_MIN} >0800
RewriteCond %{TIME_HOUR}%{TIME_MIN} <1800
RewriteRule ^(.*).html$ %{DOCUMENT_ROOT}/index.php?action=$1&day=1 [L,QSA]
RewriteRule ^(.*).html$ %{DOCUMENT_ROOT}/index.php?action=$1&day=0 [L,QSA]

Opět jsme zde zkombinovali dva RewriteCond dohromady logickým součinem. Porovnáváme serverové proměnné s aktuálním časem v hodinách a v minutách se dvěma řetězci. Pokud jsou oba dva RewriteCond vyhodnoceny pravdivě, provede se přesměrování z předchozích příkladů, jen přidáme na konec parametr day=1.

Pokud nebude podmínka vyhovovat, přesměrování pod podmínkami se vůbec neprovede a přesměruje se s využitím druhého pravidla na stránku s parametrem day=0.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Další článek martha-olsrova.com
Štítky: Články

Mohlo by vás také zajímat

Nejnovější

2 komentářů

  1. Skrisa

    Úno 7, 2010 v 23:27

    Supr clanek… konecne to nekdo pojal tak, ze nekopiruje pouze texty, ale neco rozumneho k nim prida..
    Palec nahoru kamo ;)

    Odpovědět
  2. AL

    Zář 11, 2015 v 23:46

    Dobrý den,

    sice o po 10ti letech, ale nevíte jak přesměrovat sdsd.ssd.dsd.example.webzdarma.cz na example.webzdarma.cz ?

    (To „sdsd.ssd.dsd“ tam může být cokoliv a vždy to bude zobrazovat ten web)

    Odpovědět

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *