Mod_rewrite pro hezká URL – RewriteCond
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.








Skrisa
Úno 7, 2010 v 23:27Supr clanek… konecne to nekdo pojal tak, ze nekopiruje pouze texty, ale neco rozumneho k nim prida..
Palec nahoru kamo ;)
AL
Zář 11, 2015 v 23:46Dobrý 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)