Superglobální proměnné v PHP
Tento článek je určen pro začínající programátory PHP. K jeho napsání mě přivedly neustále se opakující dotazy na různých programátorských fórech a diskusích. Oním problémem je získávání hodnot předaných v adrese stránky nebo obdržených z formuláře. Nebo jinak, tenhle článek snad již konečně odpoví na věčnou otázku: „Proč mi ten příklad z knihy nefunguje?“
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[„var“]); // vypíše 10
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ář:
<form method=“post“ action=“form.php“>
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[„user“]); // vypíše Kuba
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ý:
<form method=“post“ action=“file.php“ enctype=“multipart/form-data“>
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.
foreach($_REQUEST as $ind => $val)
{
$val=addslashes($val);
eval(„$“.$ind.“=\““.$val.“\“;“);
}
Starší komentáře ke článku
Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.
Mohlo by vás také zajímat
-
Jak lze snadno upravovat soubory v PDF?
14. září 2023 -
Jak se chránit před podvody na internetu – část 2
14. října 2024 -
Jak chránit webové stránky před Web/AI Scrapingem
27. listopadu 2024 -
Nové AI modely od Open AI a Google
22. května 2024
Nejnovější
-
Nové trendy v doménách pro osobní projekty – DIY, LIVING a LIFESTYLE
9. prosince 2024 -
Jak chránit webové stránky před Web/AI Scrapingem
27. listopadu 2024 -
Jaký monitor je nejlepší k novému Macu Mini?
25. listopadu 2024 -
Výkonný a kompaktní: ASOME Max Studio s výjimečným poměrem cena/výkon
11. listopadu 2024
Petr
Led 25, 2011 v 10:53foreach($_REQUEST as $ind => $val)
{
$val=addslashes($val);
eval(„$“.$ind.“=\““.$val.“\“;“);
}
Je to nefunkční..
Anonym
Úno 11, 2012 v 18:08eval zahodit, existuji i promene jmene definovane podle obsahu jine promene (dynamicky jmenovane). pak plati:
foreach($_REQUEST as $ind => $val)
{
$ind=addslashes($ind);$val=addslashes($val);
$$ind=$val;
}
Floyd
Říj 25, 2012 v 13:58extract($_REQUEST);
A nejlepší co jsem našel je hodit to do souboru a použít auto_prepend_file v .htaccess