Kódování URL

Každý, kdo už používal Internet nějakou dobu, si patrně všiml, že URL někdy obsahuje čísla a symboly jako %, + a =. Speciálně po provedení hledání v nějakém vyhledávači. Tyto znaky jsou výsledkem kódování URL. Když jsou přenášena data mezi webovým serverem a prohlížečem, kódování URL zajišťuje převod zakázaných a nesprávných znaků na takové, které nezpůsobí problémy.

Programátor PHP se kódováním URL nemusí zabývat, protože data z formuláře kóduje automaticky prohlížeč a PHP je automaticky dekóduje. Nicméně, pochopení kódování URL může být pro programátora užitečné, například když chce dynamicky vytvářet odkaz, který zahrnuje řetězec dotazu. Nejprve se ale podívejme blíže na to, co se stane, když je odeslán formulář. Jistě už víte, že data odesílaného formuláře jsou organizována do dvojic klíč=hodnota. Pokud máme formulář s jedním políčkem pro jméno a odesílacím tlačítkem, dostaneme dvě dvojice klíčů a hodnot:

uzivatel/Alenka
odeslat/Odeslat

Dvojice klíč/hodnota jsou prezentovány ve formátu název=hodnota a páry jsou od sebe odděleny znakem & (ampersand):

uzivatel=Alenka&odeslat=Odeslat

Znaky mezer jsou prezentovány znakem + (plus). Pokud bychom místo "Alenka" zadali "Alenka Seredova", kódovaná data by pak vypadala takto:

uzivatel=Alenka+Seredova&odeslat=Odeslat

Pokud je položka ponechána prázdná, je odeslána jednoduše s prázdnou hodnotou:

uzivatel=&odeslat=Odeslat

Když prohlížeč zakóduje dvojice klíč/hodnota, připojí je k URL určenému atributem action formuláře HTML formou řetězce dotazu. Řetězec se skládá ze znaku ? (otazník) následovaného zakódovanými dvojicemi názvů a hodnot. Výsledné URL vypadá takto:

aplikace.php?uzivatel=Alenka&odeslat=Odeslat

Prohlížeč odešle tuto hodnotu na server a PHP dekóduje řetězec dotazu a vytvoří proměnné $_REQUEST['uzivatel'] a $_REQUEST['odeslat'].

Některé znaky jsou vyhrazené a nesmí se objevit v URL (nebo řetězci dotazu, který je součástí URL). Tyto znaky jsou jednotlivě kódovány pomocí znaku % (procento) následovaného hodnotou ASCII znaku v hexadecimální podobě. Následující tabulka obsahuje některé z těchto znaků, které musí být kódovány:

Znak Kódování v URL
tabulátor %09
mezera %20
" (uvozovky) %22
( %28
) %29
, (čárka) %2C
: (dvojtečka) %3A
; (středník) %3B
< %3C
> %3E
@ %40
\ %5C
| %7C

Jak jsme si řekli dříve, znak mezery je nahrazeny znakem +, když se objeví ve dvojici klíč/hodnota v části s hodnotou. Kdekoliv jinde v URL musí být nahrazena %20. Když jsou kódovaná data zpátky dekódována, jsou znaky + opět nahrazeny mezerou. Ale co když je sám znak + obsažen v datech? Znaky, které mají v URL zvláštní význam, musí být také kódovány, aby nedošlo k záměně s jejich speciálním významem. Následující tabulka obsahuje sedm těchto znaků, jejich význam a to, jak se kódují, aby se předešlo problémům s jejich interpunkcí.

Znak Speciální význam Kódování v URL
/ Používá se pro indikaci cesty k adresáři. %2F
? Používá se na začátku řetězce dotazu. %3F
= Používá se pro spojení klíče s hodnotou. %3D
& Používá se pro oddělování dvojic klíč/hodnota. %26
+ Reprezentuje mezeru (uvnitř hodnoty). %2B
% Používá se pro kódování speciálních znaků. %25
# Používá se jako odkaz na určité místo v HTML dokumentu. %23

Nyní víme, že PHP automaticky vytváří proměnné z dat, která nalezne v řetězci dotazu. V našem příkladu dosud při odesílání formuláře HTML prohlížečem. Neexistuje důvod, proč byste nemohli řetězec dotazu vytvářet ve skriptu. PHP se nestará o to, jak byl řetězec vytvořen. Pouze ví, že když se s ním setká, má podle tohoto řetězce vytvořit příslušné proměnné. Toto chování umožňuje předávání dat proměnných z jednoho skriptu na druhý pomocí řetězce dotazu.

V prvotním souboru jmeno.php vytvoříme proměnnou $uzivatel a přidáme do něho odkaz vedoucí na další stránku - aplikace.php. Do URL odkazu přidáme ručně řetězec dotazu (HTTP GET) a můžeme přijatou proměnnou použít pro vypsání jména.

Zdrojový kód souboru jmeno.php:

<?php
  $uzivatel 
'Petra';
?>
<html>
<body>
<a href="aplikace.php?uzivatel=<?php echo $uzivatel?>">Zobrazit jméno!</a>
</body>
</html>

Zdrojový kód souboru aplikace.php:

<html>
<body>
<p>Přijaté jméno: <?php echo $_REQUEST['uzivatel']; ?></p>
</body>
</html>

Jak vidíte, předávání parametrů v URL je velice jednoduchá cesta, jak sdílet proměnné mezi skripty. Můžete předat libovolné množství parametrů a hodnot. Ale aby to nebylo tak jednoduché, vrátíme se ke kódování URL. Jednoduché řetězce jako například "Petra" lze předat jednoduše. I když například mezery a české znaky v odkazech většinou prohlížeč převádí na bezpečný tvar automaticky, nespoléhejte na to. Velké problémy totiž nastanou, pokud do řetězce dotazu ručně přidáme nějaké speciální znaky, například & nebo #. Například se pokusíme serveru poslat dotaz:

index.php?nazev=Tom&Jerry

Server však přijme ne jeden, ale dva parametry:

nazev = Tom
Jerry (bez hodnoty)

To protože znak & odděluje jednotlivé parametry v URL. Abychom se vyhnuli tomuto problému, PHP obsahuje funkci urlencode(). Tato funkce převede řetězec na tvar, který lze bezpečně předávat přes URL. Oprava by mohla vypadat takto:

<?php $uzivatel 'Tom & Jerry'?>
<a href="aplikace.php?uzivatel=<?php echo urlencode($uzivatel); ?>">Zobrazit jméno!</a>

Podobná funkce je rawurlencode(). Jediný rozdíl, je v tom, že mezery nepřevádí na znak +, ale na sekvenci %20, hodí se tudíž pro zakódování části URL, kde se vyskytuje jméno skriptu (souboru), které obsahují mezeru (například prvni skript.php), takové názvy by však svědomitý programátor neměl vůbec vytvářet.

Funkce, které provádí přesný opak (tj. rozkódování URL), jsou urldecode() a rawurldecode(). Mohlo by vás napadnout, že je použijeme pro vypsání přijaté proměnné, jako je například $_REQUEST['uzivatel'], ale nedělejte to. PHP řetězec dotazu dekóduje automaticky. Dokonce může nastat situace, kdy v URL budeme opravdu chtít předat řetězce obsahující speciální sekvence (+ nebo %20), ty se pak po rozkódování těmito funkcemi stanou obyčejnou mezerou!

 

« Obsah učebnice