| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Ze svΘ zkuÜenosti vφm, ₧e problematika p°edßvßnφ hodnot prom∞nn²ch je mnoh²m (hlavn∞) zaΦßteΦnφk∙m v PHP stßle nejasnß. ╚ßsteΦn∞ za to mohou starÜφ, ale oblφbenΘ knihy o PHP, kterΘ superglobßlnφ pole v∙bec nezmi≥ujφ, ale Φasto takΘ lenost programßtor∙m vlastnφ.
Trocha historie p°edßvßnφ prom∞nn²ch
V ka₧dΘ starÜφ uΦebnici jazyka PHP asi najdete hned na zaΦßtku podobn² p°φklad. Jde o znßmou ukßzku adresy s p°edan²mi daty, nap°φklad http://www.nejaky_server.cz?var=10 i s vysv∞tlenφm, ₧e PHP automaticky zaregistruje prom∞nnou $var a p°i°adφ jφ hodnotu 10. A jsme u skuteΦnΘho kamene ·razu. Tento postup, kdy se p°edßvanß prom∞nnß rovnou zaregistruje, nenφ p°φliÜ bezpeΦn², proto₧e relativn∞ snadno m∙₧e dojφt k podvrh∙m a nabourßnφ celΘho skriptu.
ProblΘm nastane, pokud nßÜ programßtor bude chtφt tento postup vyzkouÜet. To, zda se bude prom∞nnß automaticky registrovat, ovliv≥uje nastavenφ PHP v konfiguraΦnφm souboru php.ini, konkrΘtn∞ direktiva register-globals. Od PHP 4.2 je tato direktiva nastavena na Off, automatickß registrace prom∞nn²ch je tedy vypnuta. A to je p°esn∞ ten d∙vod, proΦ spousta novßΦk∙ dostßvß z PHP bolenφ hlavy.
Superglobßlnφ prom∞nnΘ
Zatφm jsme si pouze °ekli, proΦ p°φklady z knih p°estaly fungovat. To ovÜem programßtora uspokojφ jen st∞₧φ. Jak tedy lze tyto hodnoty zφskat? Odpov∞∩ je prostß - pomocφ superglobßlnφch prom∞nn²ch.
Definice superglobßlnφch prom∞nn²ch je vcelku prostß. Jde o p°eddefinovanß pole, obsahujφcφ hodnoty prom∞nn²ch, zφskanΘ ze serveru nebo od u₧ivatele. Tato pole jsou automaticky globßlnφ, tedy automaticky "viditelnß" odevÜad. Proto se jim takΘ °φkß automatickΘ prom∞nnΘ. Zam∞°me se nynφ na jednotlivΘ superglobßlnφ prom∞nnΘ...
Hodnoty zφskanΘ z URL
Pro ukßzku si p°edstavme fiktivnφ adresu http://www.nejaky_server.cz?var=10&mode=A. Hodnoty p°edßvanΘ pomocφ URL se takΘ naz²vajφ hodnoty p°edanΘ metodou GET. PHP automaticky vytvo°φ superglobßlnφ pole $_GET[], obsahujφcφ vÜechny p°edanΘ hodnoty. JednotlivΘ indexy jsou tvo°eny p°φmo jmΘnem p°edßvanΘ prom∞nnΘ. V naÜem p°φpad∞ tedy bude pole $_GET[] obsahovat dv∞ hodnoty indexovanΘ pomocφ jmen prom∞nn²ch:
echo($_GET["mode"]); // vypφÜe A
Hodnoty p°edanΘ p°es HTTP protokol
Hodnoty zφskanΘ z formulß°∙ se obvykle p°edßvajφ pomocφ HTTP protokolu metodou POST. Zcela analogicky PHP definuje superglobßlnφ pole $_POST[], s hodnotami prom∞nn²ch indexovanΘ pomocφ XHTML atributu name. M∞jme nap°φklad nßsledujφcφ jednoduch² formulß°:
JmΘno: <input type="text" name="user" />
<input type="hidden" name="secret" value="1" />
<input type="submit" />
</form>
Pokud tφmto formulß°em u₧ivatel odeÜle jmΘno Kuba, bude v²stup ve skriptu form.php vypadat nßsledovn∞:
echo($_POST["secret"]); // vypφÜe 1
Posφlßnφ soubor∙
Specifick² je problΘm zφskßvßnφ soubor∙ od u₧ivatele pomocφ formulß°e. Nadefinujme si jeden takov²:
tvoje fotka: <input type="file" name="photo" />
<input type="submit" />
</form>
V tomto p°φpad∞ PHP nenφ v∙bec lakomΘ a poskytne pole hned dvojrozm∞rnΘ. Prvnφ index p°edstavuje atribut name, p°evzat² z formulß°e, druh² index jednotlivΘ hodnoty t²kajφcφ se zadanΘho souboru. V naÜem p°φpad∞ to bude vypadat nßsledovn∞:
polo₧ka | v²znam |
---|---|
$_FILES["photo"]["name"] | p∙vodnφ jmΘno souboru |
$_FILES["photo"]["size"] | velikost v bytech |
$_FILES["photo"]["type"] | MIME typ souboru |
$_FILES["photo"]["tmp_name"] | doΦasnΘ jmΘno souboru, pod kter²m byl ulo₧en na serveru |
$_FILES["photo"]["error"] | chybov² k≤d |
DalÜφ p°edßvanΘ hodnoty
Zcela obdobn∞ PHP automaticky vytvß°φ pole $_COOKIES[] a $_SESSIONS[], kterß obsahujφ hodnoty zφskanΘ z cookies a relacφ (sessions). A Φist∞ pro ·plnost se hodφ zmφnit superglobßlnφ pole $_SERVER[] a $_ENV[], obsahujφcφ hodnoty p°edanΘ samotn²m serverem a prost°edφm, odkud byl skript spuÜt∞n.
VÜechny hodnoty zadanΘ u₧ivatelem
Pokud je nßm jedno, z jakΘho zdroje jsou prom∞nnΘ p°edßvßny, m∙₧eme pou₧φt automatickΘ pole $_REQUEST[], obsahujφcφ vÜechny p°edanΘ hodnoty. Osobn∞ toto pole p°φliÜ nedoporuΦuji ze dvou d∙vod∙: Pokud pou₧φvßte konkrΘtnφ pole $_GET[], $_POST[], $_FILES[]..., ihned ze zdrojovΘho k≤du poznßte nejen jmΘno p°edßvanΘ prom∞nnΘ, ale i jejφ zdroj. Tento "luxus" mi u pole $_REQUEST[] chybφ. U pole $_REQUEST[] m∙₧e navφc dojφt k problΘmu, majφ-li stejnΘ jmΘno prom∞nnΘ p°evzatΘ z r∙zn²ch zdroj∙. Potom se zaregistruje samoz°ejm∞ pouze jedna.
O tom, v jakΘm po°adφ k registraci do $_REQUEST[] dojde, rozhoduje direktiva variables_order. Nab²vß hodnoty °et∞zce sklßdajφcφho se z posloupnosti pφsmen EGPCS (poΦßteΦnφ pφsmena slov Environment, Get, Post, Cookie, Server). Jak asi tuÜφte, pozd∞ji uveden² zdroj v₧dy p°epφÜe prom∞nnΘ ze zdroje uvedenΘho d°φve, pokud majφ stejnΘ jmΘno. Nap°φklad zmφn∞n² °et∞zec EGPCS nejd°φve zaregistruje prom∞nnΘ z prost°edφ, pak prom∞nnΘ p°evzatΘ z adresy, z HTTP protokolu, z cookies a nakonec ze serveru. Pokud n∞kterΘ pφsmeno vynechßte, nebudou danΘ prom∞nnΘ zaregistrovßny v∙bec, a to ani do "sv²ch" automatick²ch polφ $_*[]! Standardn∞ je direktiva variables_order nastavena na GPCS.
Jen tak na okraj
Mimo ji₧ probran²ch polφ $_*[] v PHP existujφ starÜφ pole $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_COOKIE_VARS, $HTTP_POST_FILES, $HTTP_ENV_VARS. Tato pole jsou ale oznaΦena za deprecated (p°ekonanß) a nem∞li byste je pou₧φvat. Navφc nejsou superglobßlnφ, co₧ velmi zjednoduÜen∞ znamenß, ₧e v ka₧dΘ funkci musφte na zaΦßtku uvΘst nap°φklad global $HTTP_GET_VARS, abyste je mohli v jejφm t∞le pou₧φvat.
èpetka nostalgie
Pokud by vßm automaticky registrovanΘ prom∞nnΘ p°ece jenom z nostalgie chyb∞ly, nebo se vßm stßle necht∞lo psßt cel² nßzev pole, mßm zde pro vßs jednoduch² skript, kter² zaregistruje vÜechny polo₧ky automatickΘho pole $_REQUEST[] jako samostatnΘ prom∞nnΘ. Tento skript je takΘ dob°e pou₧iteln², pokud chcete svΘ starÜφ skripty spouÜt∞t na nov∞jÜφ verzi PHP se zakßzanou automatickou registracφ a nechce se vßm ve zdrojovΘm k≤du p°episovat vÜechna jmΘna p°edßvan²ch prom∞nn²ch.
{
$val=addslashes($val);
eval("$".$ind."=\"".$val."\";");
}