Crmgo Blog

htaccess Rewrite

htaccess Rewrite

Metaznaky Příklad: Používají se k určení skupin znaků nebo „značek“ ve vzoru. Například značky začátku nebo konce řádku. \ „Escapující“ lomítko. Následující znak za ním je považován za běžný, nikoliv za speciální znak. Znak \ se uvádí před speciálními znaky, pokud jsou potřeba v jejich původním…

htaccess Rewrite

Metasymboly

Příklad:

RewriteRule ^old(.*)$ /new.php [L,R=301]

Používají se k definici skupin znaků nebo „značek“ ve vzoru. Například značky začátku nebo konce řádku.

\ „Escapující“ lomítko. Znak následující za ním je považován za běžný, nikoliv za speciální znak. Znak \ se uvádí před speciálními znaky, pokud je potřeba je použít v jejich původní podobě. Například výraz „jpe\+g“ odpovídá pouze jednomu řetězci „jpe+g“.
^ Znak ^ označuje začátek řádku.
$ Znak $ označuje konec řádku.
! Znak záporu.
. Znak . označuje libovolný znak (kromě znaku konce řádku).
.* Nahrazuje zcela libovolnou posloupnost znaků.
".*" Najde všechny podřetězce mezi uvozovkami.
| Znak | označuje alternativu. Například výrazy „A|B“ a „(ABC|DEF)“ znamenají „A nebo B“ a „ABC nebo DEF“.
() Kulaté závorky () se používají k vymezení skupin znaků.
[...] Hranaté závorky [] se používají k vyjmenování povolených znaků. Například výraz „[abc]“ je ekvivalentní výrazu „a|b|c“, ale varianta s hranatými závorkami je obvykle rychlejší. Uvnitř závorek lze použít rozsahy: například výraz „[0-9]“ je ekvivalentní výrazu „[0123456789]“.
[^...] Invertovaná množina znaků. Pokud znaky uvnitř hranatých závorek začínají znakem ^, znamená to libovolný znak kromě těch vyjmenovaných ve závorkách. Například výraz „[^0-9]+“ znamená řetězec složený z libovolných znaků kromě číslic.
[...]* Například [abc]* – příkaz najde za sebou jdoucí znaky zadané množiny. [^abc]* – přesně naopak.
\w Písmeno, číslice nebo podtržítko _.
\d Nahrazuje libovolnou číslici.
\D Nahrazuje libovolný znak, ale ne číslici.
[0-9] Nahrazuje libovolnou číslici.
[a-z] Libovolné malé písmeno od a do z (celá sada latinských znaků).
[A-Z] Libovolné velké písmeno od A do Z.
[a-zA-Z] Libovolné písmeno od a do Z v jakémkoli případě. [a-Z] – totéž.

Doplnění: Vše, co je umístěno za znakem '#', je považováno za komentář.

Modifikátory

Příklad:

RewriteRule (.*) $1? [R=301,L]

Modifikátory se používají za běžnými znaky, speciálními znaky nebo jejich skupinami a umožňují rozšířit možnosti vzorů pro spouštění pravidel.

? Symbol se opakuje 0 nebo 1krát. Symbol ? se umisťuje za symbol (nebo skupinu symbolů), který může být přítomen, ale nemusí být. Například výrazu „jpe?g“ vyhovuje řetězec „jpg“ i řetězec „jpeg“.
* Opakuje se od 0 do 65536krát. Symbol * se umisťuje za symbol (nebo skupinu symbolů), který může chybět nebo být přítomen neomezeněkrát za sebou. Například výrazu „jpe*g“ vyhovují řetězce „jpg“, „jpeg“ i „jpeeeeeeg“.
+ Opakuje se od 1 do 65536krát. Symbol + funguje podobně jako symbol *, s tím rozdílem, že předchozí symbol musí být přítomen alespoň jednou. Například výrazu „jpe+g“ vyhovují řetězce „jpeg“ a „jpeeeeg“, ale ne „jpg“.
{n} Přesně nkrát.
{n,} Od n do 65536krát včetně.
{n,m} Od n do mkrát včetně.

Příklady použití:

^stena

Libovolné řetězce začínající slovem stena. Řetězec začínající slovem dom-stena nesplňuje kritérium.

stena$

Libovolné řetězce končící sekvencí znaků stena. Řetězec končící na stena-dom do výběru nespadne.

.*

Libovolný znak se opakuje libovolný početkrát. Do kritéria spadnou všechny řetězce.

^(.*)$

Vybrat libovolný řetězec a uložit jej jako proměnnou $1 pro další použití.

[0-9]{1,6}$

Vybrat všechny řetězce končící od 1 do 6 číslic z rozsahu 0 až 9.

^(.+)/(.+)$

Rozdělit řetězec na dvě části: před lomítkem a za ním; části řetězce budou dostupné přes proměnné $1 a $2.

Důležité! Protože modifikátor je chamtivý (greedy), do první skupiny bude zahrnuto maximální množství znaků vyhovujících vzoru. Lomítko je stejným znakem jako všechny ostatní.

Příklad použití:

RewriteRule ^(.+)/(.+)$ /?a=$1&b=$2 [R=301,L]

http://www.site.com/1/2/3/4/5 →
http://www.site.com/?a=1/2/3/4&b=5

Příznaky (Flags)

Příklad:

RewriteRule ^htaccess-fake$ - [G]
RewriteRule (.*) page.php\?%1 [L]

Příznaky jsou další volby. Uvádějí se v hranatých závorkách oddělené čárkou, například [NC] nebo [R=301,L].

R (redirect) zastaví proces převodu a vrátí výsledek klientovu prohlížeči jako přesměrování na tuto stránku (302, MOVED TEMPORARY). S tímto příznakem lze zadat jiný kód výsledku, například „R=301“ vrátí přesměrování s kódem 301 (MOVED PERMANENTLY).
F (forbidden) vrátí chybu 403 (FORBIDDEN).
G (gone) vrátí chybu 410 (GONE).
P (proxy) – podle tohoto příznaku Apache provede poddotaz (sub-request) na uvedenou stránku pomocí softwarového modulu mod_proxy, přičemž se uživatel o tomto poddotazu nedozví nic. Pokud modul mod_proxy není součástí vaší sestavy Apache, použití tohoto příznaku způsobí chybu.
L (last) zastaví proces převodu a aktuální odkaz je považován za konečný.
N (next) spustí proces převodu od prvního pravidla v pořadí.
C (chain) spojí více pravidel do řetězce. Pokud první pravidlo řetězce „nezafunguje“, celý řetězec se ignoruje.
NS (nosubreq) povoluje „zafungování“ pravidla pouze pro skutečné dotazy, přičemž se ignorují poddotazy (poddotaz může být vyvolán například zahrnutím souboru pomocí direktivy SSI).
NC (nocase) vypne kontrolu velikosti písmen při zafungování pravidla.
QSA (qsappend) přidá původní parametry dotazu (query string) k náhradě. Pokud náhrada neobsahuje nové parametry dotazu, původní parametry dotazu se přidají automaticky. Pokud je však obsahuje, bez příznaku QSA původní parametry dotazu budou ztraceny.
PT (passthrough) zastaví proces převodu a předá získaný nový odkaz dále „řetězcem“, aby nad ním mohly „pracovat“ direktivy Alias, ScriptAlias, Redirect a podobné (zatímco s příznakem L je nový odkaz považován za konečný a nepodléhá dalšímu zpracování).
S (skip) přeskočí další pravidlo, pokud toto pravidlo „zafungovalo“. Lze přeskočit více pravidel, pokud zadáte jejich počet, například: „S=3“.
E (env) nastaví proměnnou prostředí, například: „E=variable:value“.

Kontroly

Příklad:

RewriteEngine on

RewriteCond %{REQUEST_FILENAME} !-d

RewriteCond %{REQUEST_FILENAME}\.html -f

RewriteRule ^(.*)$ $1.php

Podmínky mohou používat následující kontroly:

1. Můžete před šablonu umístit znak '!', abyste označili, že šabloně neodpovídá.

2. Lze provést lexikografické porovnání řetězců:

Lexikograficky menší
Lexikograficky větší
Shoda
Lexikograficky menší nebo rovno
Lexikograficky větší nebo rovno

3. Porovnání jako celých čísel:

Číselně rovno
Číselně větší nebo rovno
Číselně větší
Číselně menší nebo rovno. Pro předejití záměně s velkým písmenem -l použijte -L
Číselně menší. Pro předejití záměně s velkým písmenem -l použijte -L

4. Testování různých atributů souborů:

Je adresář.
Je běžný soubor.
Soubor existuje.
Je symbolický odkaz.
Je symbolický odkaz. Analogie k přepínači -l.
Je běžný soubor o nenulové velikosti
Existuje zadaná URL
Je soubor spustitelný.

5. Všechny tyto kontroly mohou být také předcházeny prefixem vykřičník ('!') pro inverzi jejich hodnoty.

Proměnné

Příklad:

RewriteCond %{REQUEST_URI} /+[^\.]+$

RewriteRule ^(.+[^/])$ %{REQUEST_URI}/ [R=301,L]

HTTP_USER_AGENT Obsahuje informace o typu a verzi prohlížeče a operačního systému návštěvníka.
HTTP_REFERER Uvádí adresu stránky, ze které návštěvník na tuto stránku přišel.
HTTP_COOKIE Seznam cookies předávaných prohlížečem.
HTTP_FORWARDED Stránka, ze které uživatel přímo přešel.
HTTP_HOST Adresa serveru, např. host.com.
HTTP_ACCEPT Popisuje preference klienta ohledně typu dokumentu.
REMOTE_ADDR IP adresa návštěvníka.
REMOTE_HOST Adresa návštěvníka ve standardním tvaru – např. rt99.net.com.
REMOTE_IDENT Jméno vzdáleného uživatele. Má formát jméno.host, např. kondr.www.rtt99.net.com.
REMOTE_USER Stejné jako REMOTE_IDENT, ale obsahuje pouze jméno. Příklad: kondr.
REQUEST_METHOD Umožňuje určit typ požadavku (GET nebo POST). Musí být nutně analyzován, protože určuje další způsob zpracování informací.
SCRIPT_FILENAME Celá cesta k webové stránce na serveru.
PATH_INFO Obsahuje vše, co bylo předáno skriptu.
QUERY_STRING Obsahuje řetězec předaný jako požadavek při volání CGI skriptu.
AUTH_TYPE Používá se k identifikaci uživatele.
DOCUMENT_ROOT Obsahuje cestu ke kořenovému adresáři serveru.
SERVER_ADMIN E-mailová adresa vlastníka serveru uvedená při instalaci.
SERVER_NAME Adresa serveru, např. kondr.host.com.
SERVER_ADDR IP adresa vašeho webu.
SERVER_PORT Port, na kterém běží Apache.
 SERVER_PROTOCOL  Verze protokolu HTTP.
 SERVER_SOFTWARE  Název serveru, např. Apache/1.3.2 (Unix).
TIME_YEAR TIME_MON TIME_DAY TIME_HOUR TIME_MIN TIME_SEC TIME_WDAY TIME Proměnné určené pro práci s časem v různých formátech.
API_VERSION Toto je verze API modulu Apache (vnitřní rozhraní mezi serverem a modulem) v aktuální sestavení serveru, což je definováno v include/ap_mmn.h.
THE_REQUEST Celý řetězec HTTP požadavku odeslaný prohlížečem serveru (tj. „GET /index.html HTTP/1.1“). Neobsahuje žádné další hlavičky odesílané prohlížečem.
REQUEST_URI Zdroj požadovaný v řetězci HTTP požadavku.
REQUEST_FILENAME Celá cesta v souborovém systému serveru k souboru nebo skriptu odpovídajícímu tomuto požadavku.
IS_SUBREQ Bude obsahovat text „true“, pokud je požadavek aktuálně prováděn jako podpožadavek, „false“ v opačném případě. Podpožadavky mohou generovat moduly, které musí pracovat s dalšími soubory nebo URI, aby splnily své vlastní úkoly.

Logika provádění pravidla (RewriteRule)

Provádění pravidla zahrnuje následující kroky: nejprve mechanismus převodu vyhledá další podmínky pro toto pravidlo (příkazy RewriteCond). Je třeba si pamatovat, že z historických důvodů se další podmínky nacházejí před pravidly (RewriteRule). Pokud pro dané pravidlo nejsou definovány žádné další podmínky, provede transformační mechanismus přímo uvedenou transformaci aktuální URL a přejde k dalšímu pravidlu. Pokud však pro prováděné pravidlo (RewriteRule) existují další podmínky uvedené PŘED NÍM v příkazech RewriteCond, spustí se interní cyklus pro zpracování těchto podmínek v pořadí, v jakém jsou uvedeny, shora dolů.

Pokud alespoň jedna z dostupných podmínek pro pravidlo NENÍ splněna, dojde k zastavení spuštěného procesu provádění pravidla a transformace URL definovaná v pravidlu NENÍ provedena. Aby bylo spuštěné pravidlo provedeno až do konce a změnilo URL, musí být splněny VŠECHNY další podmínky uvedené v příkazech RewriteCond před tímto pravidlem!

Zde je třeba dodat, že příkazy RewriteCond jsou ve výchozím nastavení spojeny operátorem AND do jednoho složeného podmínkového výrazu. Tento operátor (AND) se ve výchozím nastavení nezapíše. Odtud pramení logika, že pro úspěšné dokončení transformace URL musí být všechny další podmínky pravdivé (protože jsou spojeny pomocí AND). Příkazy RewriteCond lze však spojit podmínkou OR pomocí přepínačů (viz syntaxe příkazu). Na to je třeba pamatovat při zadávání dalších podmínek.

Syntaxe příkazu RewriteRule:

RewriteRule Шаблон Подстановка [Флаги]

Příklad:

RewriteRule ^(.*)$ index.php?/$1 [L,QSA]

Kde:

1.    RewriteRule  – je název příkazu – pravidla.
2.    Šablona  – je to právě ta podmínka, jejíž splnění spustí provádění pravidla. Tato podmínka – Šablona – je regulární výraz kompatibilní s Perl, který se aplikuje na aktuální URL.
3.    Nahrazení  – je to právě algoritmus změny URL, tedy pravidlo změny (transformace) URL.
4.    [Přepínače] nahrazení – třetí argument příkazu RewriteRule. Přepínače jsou oddělené čárkami, velká speciální písmena uzavřená ve čtvercových závorkách. Přepínače doplňují transformaci URL.

Parametry v pravidle jsou zapsány na jeden řádek počínaje názvem příkazu a jsou odděleny mezerami.

Nyní si rozeberme příklad pravidla RewriteRule:

RewriteRule ^(.*)$ index.php?/$1 [L,QSA]

1.    ^(.*)$ - to je Šablona, regulární výraz, který se aplikuje na aktuální URL. Kdo zná regulární výrazy, může jej číst takto: hledat v aktuálním řetězci URL od začátku řetězce (znak ^) do konce řetězce (znak $) libovolný znak (znak .) v množství od nuly do nekonečna (znak *). Protože tento regulární výraz obsahuje závorky (), ta část URL, která odpovídá podmínce v závorkách, bude zachycena do proměnné pro substituci $1, kterou můžeme později použít v Substituci nebo v PorovnávanýŘetězec (to je v direktivě RewriteCond, o ní níže).
2.     index.php?/$1 - Substituce – to je vlastně pravidlo pro transformaci URL. Zápis index.php?/$1 znamená, že řetězec nového, transformovaného URL by měl být složen ze dvou částí, kde první část řetězce je konstantní hodnota index.php?/ a druhá část řetězce je hodnota z proměnné pro substituci $1. Zde si vzpomeneme, že v $1 je uložena ta část URL, která odpovídala regulárnímu výrazu v závorkách z parametru Šablona. Výsledkem dostaneme transformované URL ve tvaru index.php?/URL, na které bylo provedeno volání. Jinými slovy, pro všechny požadavky dochází k internímu přesměrování na soubor index.php.
3.    [L,QSA] – přepínače, kde 'last|L' - poslední pravidlo, což znamená - zastavit proces transformace na tomto místě a nepoužívat již žádná další pravidla transformace pro URL. 'qsappend|QSA' - přidat řetězec dotazu - Tento přepínač označuje mechanismu transformace, aby přidal, nikoli nahradil, řetězec dotazu z URL k existujícímu v řetězci Substituce. Použijte to, když chcete přidávat další data do řetězce dotazu pomocí direktiv transformace.

Rychlé odkazy

Rychlý přehled mod_rewrite

Rychlý přehled mod_rewrite obsahuje seznam přepínačů pro direktivy RewriteRule a RewriteCond, seznam serverových proměnných, příručku k regulárním výrazům a několik příkladů běžných pravidel.

Rychlý přehled regulárních výrazů

Rychlý přehled je obecnou příručkou k šablonám regulárních výrazů bez ohledu na specifika nějakého jazyka.

Závěr

Nezapomeňte v regulárním výrazu escapovat speciální znaky. Někdy se zapomíná escapovat tečku, když má vystupovat právě jako tečka, nikoli jak je zvykem v regulárních výrazech – jako libovolný znak.

Navíc nezapomeňte celý blok pravidel pro mod_rewrite obalit do tagu: <IfModule mod_rewrite.c></IfModule>

Nepíšte zbytečně mnoho direktiv pro mod_rewrite, zapisujte pouze ta pravidla převodu, která skutečně potřebujete. Zvláště buďte opatrní u externích přesměrování – jde o přesměrování, která jsou provedena odesláním serverové hlavičky klientovi s kódem NENÍ 200 (vracení kompletní stránky), ale s jiným kódem (nejčastěji 301 a 302), což vede k přesměrování v prohlížeči klienta na jinou URL, tedy k provedení nového požadavku na straně klienta.

Každé externí přesměrování proto vždy způsobuje ztrátu času při zpracování požadavku, protože je třeba odeslat klientovi odpověď, kterou musí přečíst a znovu opakovat požadavek na nové URL. Jedná se o časově náročnou proceduru. Proto by měla být přesměrování použita pouze tehdy, pokud jsou skutečně nezbytná.

Poznámka: příspěvek mohl vzniknout s pomocí AI a lidskou redakcí. Odpovědný: Dmytro Lomaka, Kaltenkirchen.