Tömbök III.
Előredefiniált változók
A PHP kódban sokszor szükség lehet arra, hogy a szervertől (ami a PHP kódot HTML kóddá fordítja) különféle információkat tudjunk meg. A PHP kódban erre használhatunk bizonyos előre definiált változókat, melyek neve előre meghatározott, vagyis nem mi adjuk meg tetszőlegesen, és nem is mi hozzuk őket létre. Ezekben olyan információk vannak, melyekhez más módon többnyire nem tudunk hozzáférni, például előre definiált változókban tárolódik egy űrlap által elküldött adat, vagy az aktuálisan futó PHP kódot tartalmazó fájl neve, stb. Itt csak néhány előre definiált változót ismerünk meg, és ezeket is csak felületesen, mivel többnyire az űrlapok kezelésénél lesz rájuk szükség.
A legtöbb előre definiált változó többféle módon is elérhető, mi ezek közül csak egyfélével fogunk foglalkozni: az előre definiált változók bekerülnek $_VALAMI["kulcs"] alakú asszociatív tömbökbe. A VALAMI helyén egy csupa nagybetűkből álló szó van. A tömb neve a változó kategóriájára utal, mindig aláhúzás karakterrel kezdődik, és csupa nagybetűből áll, például $_POST, $_SERVER, stb.
Ezek asszociatív tömbök, vagyis egy kulccsal érhetünk el egy bizonyos változót. Ezeket a változókat szuperglobális változóknak szokták nevezni, mivel függvényeken kívül és belül is bárhol elérhetőek.
A $_POST és a $_GET asszociatív tömbbe kerülnek az űrlap által küldött adatok, hogy melyikbe, az attól függ, hogy az elküldésre a post vagy a get metódust használtuk-e. Ez azt jelenti, hogy az űrlap <form> tegjének method paramétere "post" vagy "get" értéket kapott-e (ld. Űrlapok 2. lecke). Például egy
<form method="post" action="fájlnév"> <input type="text" name="nev" /> <!-- szövegbeviteli mező --> <input type="submit" /> <!-- űrlapelküldő gomb --> </form>
HTML-kódú űrlap esetén az űrlapon egy szövegbeviteli mező és egy gomb van. Ha a szövegbeviteli mezőbe beírunk valamit, majd ezt az űrlapot elküldjük (a gombra kattintva lehet elküldeni), akkor megnyílik a <form> teg action paraméterébe beírt fájl, és abban a fájlban a $_POST asszociatív tömbbe kerülnek az űrlap által küldött adatok. A tömb kulcsait az űrlapelemek name paraméterei határozzák meg, vagyis az előző esetben a szövegbeviteli mezőbe írt karakterlánc a $_POST["nev"] tömbelembe kerül. Ha a <form> teg method paramétere "get" értékű, akkor ugyanez a helyzet, csak ekkor a $_GET tömbbe kerülnek az űrlap által küldött adatok. Ekkor a $_GET["nev"] tömbelembe kerül a mezőbe írt szöveg.
A $_GET tömbbe kerülnek azok a karakterláncok is, melyek az URL-ben továbbítódtak (az URL az a szöveg, amit a böngésző címsorába beírva az oldal megnyílik). Például a php.sikerweb.hu egyik oldalának URL-je: http://php.sikerweb.hu/oktato/printget. Ennek az oldalnak adatokat lehet továbbítani úgy, ha például az URL-t így adod meg:
http://php.sikerweb.hu/oktato/printget?nev=valami&jelszo=nemtudom (Próbáld ki!)
Ebben az esetben a $_GET["nev"] tömbelembe kerül a "valami" karakterlánc, a $_GET["jelszo"]-ba pedig a "nemtudom". A $_POST és a $_GET asszociatív tömbökről bővebben olvashatsz az Űrlapok és fájlkezelés rész első három leckéjében!
Példaként megemlítem, hogy a $_SERVER tömbben különféle, a szerver által küldött információk szerepelnek. Például a $_SERVER["PHP_SELF"] elem tartalmazza az aktuálisan futó php fájl nevét. Most kiíratom PHP kóddal ezt a változót: /index.php. Elvileg most az index.php fájl php.sikerweb.hu tárhelyen belüli elérési útja íródott ki dőlt betűkkel, mivel itt valójában minden oldalt az index.php jelenít meg.
Még egy fajta előre definiált asszociatív tömböt nézünk meg, a $GLOBALS tömböt (ez az eddigiektől eltérően nem kezdődik aláhúzás karakterrel). A 10. leckében a függvények kapcsán említettük, hogy a függvények belsejében nem lehet elérni a globális hatókörben (függvényen kívül) létrehozott változókat, ha azt nem adjuk át paraméterként. Azonban erre is van mód, bizonyos esetekben szükség is lehet rá. Egy függvény törzsében a globális változók a $GLOBALS asszociatív tömb elemeiként érhetőek el. Például, ha van egy $valtozo nevű változó a globális hatókörben, akkor a függvény törzsében erre a $GLOBALS["valtozo"] névvel hivatkozhatunk. Ez úgy keletkezett, hogy a változó neve (a dollárjel nélkül) lett a tömb kulcsa. A globális változókat így a függvény nem csak felhasználni, de megváltoztatni is képes. Példa:
function szum_ab(){
$szum = $GLOBALS["a"] + $GLOBALS["b"];
$GLOBALS["a"] = NULL;
$GLOBALS["b"] = NULL;
return $szum;
}
$a = 20; $b = 3;
print szum_ab();
Ez a program a 23-as számot fogja kiírni, és egyébként mindkét változót megsemmisíti. Ha a globális változó egy tömb, akkor magára a tömbre a fenti módszerrel tudunk hivatkozni. Például, ha van egy $tomb nevű tömb, akkor függvényen belül a $GLOBALS["tomb"] névvel tudjuk elérni. Tehát ezt most úgy kell elképzelni, hogy a $GLOBALS egy asszociatív tömb, aminek a $GLOBALS["tomb"] eleme szintén egy tömb. Erről ugyan nem volt szó, de egy tömb eleme nem csak egyszerű típusú változó lehet, hanem tömb is. Ilyen képződményekről a 19. leckében lesz szó. Elöljáróban annyit, hogy ennek például a 3-as indexű elemére így hivatkozhatunk: $GLOBALS["tomb"][3]. Vagy ha a globális tömb asszociatív, akkor például egy $admin["jelszo"] elem függvényen belül a $GLOBALS["admin"]["jelszo"] hivatkozással érhető el.
Tömbkezelő függvények
Tömbökkel rengeteg műveletet lehet elvégezni, és a legtöbb gyakori műveletre rendelkezésre állnak beépített függvények. Az alábbiakban csak három, viszonylag hasznos függvényt mutatok meg.
explode()
Ez a függvény két karakterláncot vár paraméterként, és visszatérési értéke egy tömb. Arra való, hogy a második paraméterként átadott hosszú karakterláncot feldarabolja (a "hosszú" itt csak egy jelző, amivel megkülönböztetem az első paramétertől). Az egyes darabokat berakja egy tömbbe, és ez lesz a visszatérési érték. Az első paramétereként a hosszú karakterláncban lévő elválasztót kell megadni. Például, ha szóközök választják el a darabokat, amiket a tömbbe akarunk rakni, akkor az első paraméternek egy szóközt kell megadni.
$str = "répa, retek, saláta, paprika, zeller, uborka";
$zoldseg = explode(", ", $str);
Ebben a példában az $str karakterláncban az egyes szavak egy vesszővel és egy szóközzel (", ") vannak elválasztva, így ezt adhatjuk meg első paraméternek. Ekkor a $zoldseg tömb:
$zoldseg[0] = "répa"; $zoldseg[1] = "retek"; $zoldseg[2] = "saláta"; $zoldseg[3] = "paprika"; $zoldseg[4] = "zeller"; $zoldseg[5] = "uborka";
Tehát itt az elválasztó karakterlánc a ", " volt, így a második paraméter eszerint lett szétdarabolva. Látszólag ennek a függvénynek nincs túl sok haszna, ennek ellenére igen gyakran használatos például szöveges fájlok kezelése esetén (az Űrlapok és fájlkezelés rész második felében ilyennel fogunk foglalkozni). Például, ha beolvastunk egy szöveges (mondjuk txt) fájlt a $file változóba, akkor az egyes sorait így lehet szétválasztani:
$sor = explode("\n", $file);
Így például a $sor[9] a tizedik sort tartalmazza (mivel az indexelés 0-val kezdődik). Azért a helyzet ennél valamivel bonyolultabb, mivel 3-féle újsor-karakter létezik, így nem tudhatjuk mindig, hogy a fájlban milyenek vannak, de ezzel a problémával majd a fájlkezelésnél foglalkozunk.
sort()
A sort() függvénnyel egy tömböt tudunk növekvő sorrendbe rendezni. Azért érdemes a rendezést beépített függvényre bízni, mert a rendező algoritmusokra jellemző, hogy minél gyorsabb, annál bonyolultabb. Paramétere a rendezni kívánt tömb, második paraméterként megadhatjuk a rendezés módját, de ez a paraméter elhagyható. Visszatérési értéke nincs, az első paramétereként kapott tömböt változtatja meg. A rendezni kívánt tömb lehet sima vagy asszociatív is, a tömb elemeit érték szerint (és nem kulcs szerint) rendezi. A függvény használható számokat és karakterláncokat tartalmazó tömbök rendezésére is. A számok nagyság szerint lesznek növekvő sorrendbe rendezve, a karakterláncokat pedig abc-sorrendbe rakja. Karakterláncok esetén azonban nem működik kifogástalanul, ugyanis rendezésre az ASCII-kódtáblát használja, amiben a karakterek valamilyen sorrendben helyezkednek el. Ezt a táblát megnézheted a Windows Karaktertábla nevű programjával (elvileg a Start menüben a Programok -> Kellékek -> Rendszereszközök -> Karaktertábla útvonalon érhető el). A lényeg az, hogy a táblában először az angol abc nagybetűi szerepelnek szépen sorrendben, majd a kisbetűk, az ékezetesek viszont ezután össze-vissza. Így például a nemrég létrehozott $zoldseg tömböt jól fogja rendezni, de nézzük például ezt:
$nevek = array("Ödön", "hülyegyerek", "Gedeon", "Ákos", "okostojás");
sort($nevek);
for ($n = 0; $n < 5; ++$n){
print $nevek[$n].", ";
}
Ekkor az alábbi kemenetet kapjuk:
Gedeon, hülyegyerek, okostojás, Ákos, Ödön,
Nyilván a helyes sorrend ez lenne:
Ákos, Gedeon, hülyegyerek, okostojás, Ödön,
feltéve, hogy a kis- és nagybetűket egyenrangúnak tekintjük (általában így szokták). Sajnos nincs a PHP-ben olyan beépített függvény, ami támogatja az ékezetes betűk sorbarendezését, de a következő leckében megpróbáljuk megoldani ezt a problémát egy másik rendező függvénnyel.
print_r()
Ez a függvény a szó szoros értelmében nem tömbök kezelésére szolgál, és más változók esetén is használható. Mikor írjuk a programot, sokszor jó lehet, ha gyorsan ki tudnánk íratni, hogy mit tartalmaz egy változó. Ez például akkor lehet hasznos, ha nem úgy működik a program, ahogy szeretnénk, és ki kéne deríteni, hogy mi a hiba. Egy egyszerű típusú változó értékét persze simán ki lehet íratni a print függvénnyel, de egy tömb kiíratásához már ciklust kell írni. Hogy egy sima ellenőrzéshez ne kelljen állandóan ciklust írni, egyszerűen meghívhatjuk a print_r() függvényt. Egy paramétere van, ami bármilyen típusú változó lehet (de legtöbbször tömböknél szokás használni), visszatérési értéke nincs. Mellékhatása az, hogy kiírja a változó értékét olvasható formában.
Tegyük fel, hogy gyorsan ki szeretnénk íratni, hogy mi van a fent létrehozott $nevek tömbben! Ezt így tehetjük meg:
print_r($nevek);
Ekkor ez fog kiíródni:
Array ( [0] => Ödön [1] => hülyegyerek [2] => Gedeon [3] => Ákos [4] => okostojás )
Ha megnézzük a PHP által létrehozott HTML kódot, láthatjuk, hogy az egyes tömbelemek között sortörések vannak. A HTML nyelvben azonban egy sortörés csak egy szóközt hoz létre, ezért a böngészőben egy sorban látszik az egész. Ha olvashatóbb formában akarjuk kiíratni, használjuk a <pre>...</pre> tegeket, az ezek közé írt szöveg úgy fog megjelenni a böngészőben, ahogy a HTML kódban látszik. Vagyis ha ezt írjuk:
print "<pre>"; print_r($nevek); print "</pre>";
akkor ez fog kiíródni:
Array
(
[0] => Ödön
[1] => hülyegyerek
[2] => Gedeon
[3] => Ákos
[4] => okostojás
)
Látható, hogy a tömb "értékét" úgy írja ki a függvény, hogy a tömbben lévő kulcs-érték párokat jeleníti meg [kulcs] => érték formában.
Házi feladat
1.) Írj egy függvényt, ami kiírja az összes globális változó nevét és értékét! Határozzuk meg, melyek azok a globális változók, melyek akkor is léteznek, ha nem hoztunk létre semmilyen változót!
Tehát ki kell íratni a $GLOBALS tömböt. Mivel ez csak egy közönséges asszociatív tömb, ezért a foreach szerkezettel tudjuk kiíratni ugyanúgy, mint bármilyen más asszociatív tömböt:
function globalis_valtozok(){
foreach ($GLOBALS as $kulcs => $ertek){
print $kulcs.": ".$ertek."<br />";
}
}
Akkor most próbáljuk ki úgy, hogy berakjuk a php kód elejére ezt a függvényt, majd rögtön meg is hívjuk! Ekkor az alábbi kimenetben gyönyörködhetünk:
GLOBALS: Array
_POST: Array
_GET: Array
_COOKIE: Array
_FILES: Array
Semmilyen változót nem hoztunk létre, mégis van pár előredefiniált változó. Mivel a print értékként azt írta ki, hogy Array, ezért sejthetjük, hogy mindegyik változó egy tömb. Ha kíváncsiak vagyunk rájuk, ezeket is kiírathatjuk. Egyébként ha a print_r() függvényt meghívjuk a program elején, akkor sokkal egyszerűbben kiírathatjuk az összes tömböt egyszerre. Ebből az is kiderül, hogy a $_POST és a $_GET tömb üres (feltéve ha nem továbbítottunk változókat az előző leckében leírt módon). A $_FILES tömb az űrlap segítségével feltöltött fájlok adatait tárolja (az űrlapoknál részletesebben foglalkozunk vele), ha nem töltöttünk fel semmilyen fájlt, akkor üres. A $_COOKIE tömb úgynevezett sütiket tárol. A sütik olyan változók, melyeket weboldalak hoznak létre (pl. PHP-vel is létrehozhatunk sütiket), ezek aztán a látogató számítógépén tárolódnak egy ideig. Ha a látogató később ismét az oldalra lép, a sütikből kiolvashatunk olyan adatokat, melyeket a legutóbbi látogatáskor eltároltunk a látogató gépén (feltéve ha azok nincsenek letörölve). A sütiket egyébként a böngésző beállításainál a felhasználó letilthatja, így bizonyos esetekben nem tudjuk sok hasznukat venni. A sütikkel itt nem foglalkozunk bővebben, mivel az már nem az "Alapok" kategória.
2.) Rakd be egy tömb elemeibe az aktuális évet, hónapot, napot, percet, órát és másodpercet! Próbáld meg megvalósítani a programot egyetlen utasítással (minden utasítás pontosvesszővel zárul, tehát legfeljebb egy pontosvessző lehet a programban)!
Ezeket az adatokat ugyebár a date() függvénnyel tudjuk meghatározni, ami azonban egy karakterláncot ad vissza. Ezt tömbbé tudjuk alakítani az előző leckében tanult explode() függvénnyel. Ha egy utasításba kell tömörítenünk az egészet (márpedig a feladat kitalálójának ilyen idétlen kívánságai vannak :D), akkor a date() függvényt kell használni az explode() második paramétereként. Az első paraméter az elválasztó karakterlánc, így ha szét is akarjuk választani a fenti 6 adatot, akkor a date()-et nem hívhatjuk például date("Y.m.d H:i:s", time()) alakban, hanem minden adat közt ugyanazt a karakterláncot kell használni. Például:
$tomb = explode(".", date("Y.m.d.H.i.s", time()));
Ez a date() függvény valami ilyesmit ad vissza: "2009.08.20.19.54.34". Ezt a karakterláncot aztán a pontok segítségével darabolhatjuk szét. A feladat kívánsága teljesült, a programban csak egy pontosvessző van, feltéve ha nem ezt használtuk a szétválasztásra.
3.) Írj egy függvényt, ami az összes addig létrehozott, egész szám típusú globális változót berakja egy tömbbe, és a tömböt visszaadja csökkenő sorrendbe rendezve! A beépített függvények közül csak a sort()-ot használd!
A feladat első fele nem nehéz, csak létre kell hozni egy tömböt, majd a $GLOBALS tömbből bele kell rakosgatni az értékeket, ha azok egész számok. Ez utóbbit az is_integer() függvénnyel ellenőrizhetjük (ld. 14. lecke). Egy lehetséges megoldás:
function gtomb(){
$glob = array();
foreach ($GLOBALS as $kulcs => $ertek){
if (is_integer($GLOBALS[$kulcs])){
$glob[] = $ertek;
}
}
sort($glob);
$glob_rev = array();
for ($n = count($glob) - 1; $n >= 0; --$n){
$glob_rev[] = $glob[$n];
}
return $glob_rev;
}
Miután beraktuk a $glob tömbbe a számokat, csökkenő sorrendben kell visszaadnunk. Ezt úgy csinálhatjuk meg, hogy növekvő sorrendbe rendezzük a sort() függvénnyel, majd egy ciklussal beolvassuk visszafele. A beolvasott értékeket berakosgatjuk egy másik tömbbe, majd ezt visszaadjuk. Ha visszafele olvassuk a tömböt, akkor a ciklusváltozó kezdőértéke az utolsó elem indexe count($glob)-1. Az alábbi módon kipróbálhatjuk:
$a = 24; $b = 10; $c = 30; $d = 1; $e = -3; $f = 9; print "<pre>"; print_r(gtomb()); print "</pre>";
Ha más egész számok is létre lettek hozva a program korábbi részében, akkor persze azok is benne vannak a $GLOBALS tömbben, így azok is kiíródnak a fenti példában.







