Když byla řeč o [odkaz]komunikaci funkce s okolním kódem[/odkaz], zmínili jsme, že ve funkci nelze jednoduše používat proměnné definované okolním kódem. Může za to věc, které se říká kontext (v angličtině scope). Z hlediska proměnných každá funkce má svůj kontext (v případě objektů metoda a ještě existuje kontext samotného objektu). Kromě toho existuje ještě hlavní kontext samotného skriptu.
<?php function mojeFunkce() { // zde je kontext funkce mojeFunkce$kontext = "Kontext mojeFunkce"; echo "<p>$kontext</p>"; }
function druhaFunkce() { // zde je kontext funkce druhaFunkce
$kontext = "Kontext druhaFunkce"; echo "<p>$kontext</p>"; mojeFunkce(); // přechod do jiného kontextu echo "<p>$kontext</p>"; // opět v kontextu druhaFunkce }
// hlavní skript $kontext = "Kontext skriptu"; echo "<p>$kontext</p>"; druhaFunkce(); // přechod do jiného kontextu echo "<p>$kontext</p>"; // opět v kontextu hlavního skriptu ?>
Kontext hodlající použít globální proměnné musí nejdřív označit, které proměnné chce jako globální používat. K tomu
slouží klíčové slovo global
. Proměnná označená jako globální se pak chová, jako bychom byli stále
v globálním kontextu.
Přepišme si příklad výše s použitím globálních proměnných:
<?php function mojeFunkce() { global $kontext; // nastavíme $kontext jako globální proměnnou$kontext = "Kontext mojeFunkce"; echo "<p>$kontext</p>"; }
function druhaFunkce() { global $kontext; // nastavíme $kontext jako globální proměnnou
$kontext = "Kontext druhaFunkce"; echo "<p>$kontext</p>"; mojeFunkce(); // přechod do jiného kontextu echo "<p>$kontext</p>"; // opět v kontextu druhaFunkce }
// hlavní skript $kontext = "Kontext skriptu"; echo "<p>$kontext</p>"; druhaFunkce(); // přechod do jiného kontextu echo "<p>$kontext</p>"; // opět v kontextu hlavního skriptu ?>
Hlavní kámen úrazu globálních proměnných je právě to, že jsou globální. Ve složitějších skriptech je těžké dohlédnout, kde všude se globální proměnná používá a kde a kdy se může změnit. To pak často vede k problému zvanému „action at a distance”, do češtiny to lze přeložit jako „vzdálené působení”, kdy změna jednoho místa programu má nečekané dopady v úplně jiné části programu.
Zároveň jeden z hlavních přínosů funkcí je, že můžete řešení jednoho konkrétního problému oddělit a pak ho používat opakovaně na různých místech. Globální proměnné naopak funkci svazují s okolním prostředím a její použití jinde znesnadňují. Funkce by v ideálním případě měla být uzavřená entita nezávislá na okolním prostředí (v objektově-orientovaném programování je taková uzavřená entita objekt).
Například u různých nastavení aplikace se může stát, že chcete proměnnou, která se na jednou nějak nastaví a pak by k ní byl globální přístup pro čtení. To ovšem není globální proměnná, ale konstanta. Místo například:
<?php $pocet = 5; // $pocet simuluje nějaké globální nastavení v aplikacifunction vypisPocet() { // Pozn.: Toto je jen pro ukázku. // Reálně by takováto funkce neměla smysl global $pocet;
echo $pocet; } ?>
<?php define("POCET", 5);function vypisPocet() { echo POCET; } ?>
Všechny superglobální proměnné v PHP jsou typu pole. S $_GET, $_POST a $_REQUEST jsme se v rámci tohoto kurzu už setkali, ale existují i další. I když použití všech z nich nebudeme teď do detailu rozebírat, můžete následující seznam používat i později jako referenci, kde jaký typ dat hledat.
<input type="file">
var_dump($_SERVER);
global
.
Máte-li globální proměnnou třeba $promenna
, můžete k ní přistupovat i pomocí $_GLOBALS["promenna"]
.
var_dump($_ENV);
zjistit, co všechno je k dispozici.
Existence superglobálních proměnných a fakt, že jsou to pole, by mohla vést k nápadu je zneužívat jako jakési globální úložiště dat. To je ovšem špatný nápad, který může vnést do skriptu bezpečnostní díry a vytvořit extrémně matoucí kód.
Všechny superglobální proměnné s výjimkou $_SESSION byste v běžném skriptu měli používat jen pro čtení, tzn. skript by je neměl nijak měnit. Pokud potřebujete s nějakou hodnotou dál pracovat, zkopírujte si ji do lokální proměnné.