V minulém dílu článku mod_rewrite a hezké url jsem Vám ukázal pár jednoduchých přepisů pro domény nižších řádů, přesměrování na url s / bez www, zpětné přesměrování ze subdomény na doménu a na konec samotný přepis hezkých url pro jednu a dvě proměnné. V druhém dílu seriálu se pokusím popsat základní problémy, které mohou nastat s použitím mod_rewrite a uvedu některé další příklady. 

Například jsem se často setkal s věčným opakováním RewriteEngine On a RewriteBase před každám pravidlem: ne, není nutné to stále opakovat. Co ale musí být u každé další proměnné uvedeno, je RewriteCond. Podmínka RewriteCond testuje, zda-li soubor či adresář daného jména neexistuje. (! negace, - parametr, d=dir - složka, f=file - soubor)

# mujweb.cz/?page=neco > mujweb.cz/neco/

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)/?$ ?page=$1

Když se tedy znovu podíváme na základní příklad z prvního dílu: RewriteEngine On - zapneme mod_rewrite. RewriteBase - budeme vycházet z kořenového adresáře. RewriteCond - podmínka, otestujeme možnou existenci souboru či adresáře se stejným jménem. REQUEST_FILENAME je speciální proměnná právě pro modul mod_rewrite. No a RewriteRule je pouze regulární výraz, první v pořadí je výsledná url, druhý výraz je skutečná url, kterou budeme podstrkávat.

Nejčastější problémy při použití mod_rewrite jsou dva: nefungují styly, nenačtou se obrázky. K vyřešení můžeme použít element <base>, nebo absolutní odkazy. Jak celé i s http, tak pouze absolutní cesty v rámci vlastního webu začínající lomítkem. Pokud ani jedno nepomůže, problém hledejte v samotném .htaccessu. Pokud zapomenete otestovat možnost existence souboru / složky, styly a obrázky se Vám nemusí vůbec načíst.

Jestli si myslíte, že musíte používat adresy ve tvaru /?page=neco abyste nebyli ochuzeni o pěknou adresářovou strukturu, tak Vás rád vyvedu z omylu: pomocí následujícího přepisu můžeme podstrčit pěknou url i souborům s koncovkou *.php:

# clanek.php => /clanek/

RewriteEngine On
RewriteBase /

RewriteCond %{ENV:REDIRECT_STATUS} !^$
RewriteRule .* - [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ $1.php [L]

RewriteCond %{REQUEST_URI} !.[[:alnum:]]+$
RewriteRule ^(.+[^/])$ /$1/ [R=301] 

Tento přepis ale není příliš propracovaný: pokud zadáme adresu bez lomítka, vyskočí chyba 404. To vyřešíme velice snadno přidáním posledních dvou řádků, které automaticky doplní lomítko na konec adresy. Při zadání adresy bez lomítka proběhne přesměrování na správnou url, kde už se načte požadovaný soubor. Pokud samotný soubor pracuje dále s proměnnými, adresy mohou vypadat následovně: /clanek.php?id=20 > /clanek/?id=20

A že je vždy potřeba dynamických stránek pro mod_rewrite? Výše uvedené lze použít i u obyčejných statických stránek s příponou *.html. Stačí změnit jeden řádek:

# soubor.html => /soubor/

RewriteEngine On
RewriteBase /

RewriteCond %{ENV:REDIRECT_STATUS} !^$
RewriteRule .* - [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ $1.html [L]

RewriteCond %{REQUEST_URI} !.[[:alnum:]]+$
RewriteRule ^(.+[^/])$ /$1/ [R=301]

Automatické přidání lomítka na konec adresy pak můžeme použít i samostatně: (doporučuji)

RewriteCond %{REQUEST_URI} !.[[:alnum:]]+$
RewriteRule ^(.+[^/])$ /$1/ [R=301]

Na závěr se ještě podíváme na příznaky. To jsou ta písmenka v závorce za každým z pravidel:

Příznaky (flags)

V některých přepisech je nutné použít takzvané příznaky (flags), které mají různé významy. Uvedu zde nejpoužívanější: 

[L] (last) Poslední pravidlo - další překlad adresy již nebude požadován. pokud se adresa jednou přeloží, nebude se již zkoušet v dalších podmínkách.
[R] (redirect)   Dočasné přesměrování
[R=301]     Trvalé přesměrování
[QSA]  (query string append)   Do výsledků se přidá i celý řetězec za otazníkem původního požadavku.
[NC] (no-case)   Nerozlišovat velikost písmen - dobré například při přesměrování na jiný web.