PHP kézikönyv
Előző | 11. Fejezet. Típusok | Következő

# Tömbök

A PHP tömbjei rendezett leképezéseket valósítanak meg. A leképezés értékeket rendel kulcsokhoz. Ez a típus sokféleképpen használható, mint egy hagyományos tömb, egy lista (vektor), hash tábla, szótár, kollekció, halmaz, sor, és mások. Mivel egy újabb PHP tömb szerepelhet értékként, könnyen szimulálhatsz fákat.

Az említett struktúrák leírása ezen kézikönyv kereteibe nem fér bele, de legalább egy példát mutatunk mindegyikre. További információkért külső forrásokat kell igénybe venned erről az igen széles témáról.

## Szintaxis

### Tömb létrehozása az array() nyelvi elemmel

Egy array (tömb) típusú változót az array() nyelvi elemmel tudsz létrehozni, amely számos vesszővel elválasztott kulcs => érték párt vár.

    array( [kulcs =>] érték
         , ...
         )
    // a kulcs lehet integer vagy string
    // az érték bármilyen érték lehet

`<?php $arr = array("ize" => "bigyo", 12 => true); echo $arr["ize"]; // bigyo echo $arr[12]; // 1 ?>`

A kulcs lehet integer vagy string típusú. Ha a kulcs egy integer szabályos reprezentációja, akkor egészként értelmezi. (azaz a "8"-at 8-ként értelmezi, a "08"-at pedig "08"-nak). Ha a kulcs-nak valós értéket adsz meg, akkor azt egésszé (integer) alakítja. PHP-ben nincs külön indexelt és asszociatív tömb típus, csak egyféle tömb típus van, amely tartalmazhat mind egész mind string indexeket.

Az érték bármilyen típusú lehet.

`<?php $arr = array("tombocske" => array(6 => 5, 13 => 9, "a" => 42)); echo $arr["tombocske"][6]; // 5 echo $arr["tombocske"][13]; // 9 echo $arr["tombocske"]["a"]; // 42 ?>`

Ha nem adsz meg kulcsot egy adott értékhez, akkor annak a kulcsa az egész típusú indexek maximuma + 1 lesz. Ha olyan kulcsot adsz meg, amelyhez már létezik hozzárendelt érték, az érték felül lesz írva.

`<?php // Ez a tömb ugyanaz mint... array(5 => 43, 32, 56, "b" => 12); // ...ez a tömb array(5 => 43, 6 => 32, 7 => 56, "b" => 12); ?>`

Figyelem
Az indexgenerálás fent leírt algoritmusa PHP 4.3.0-tól megváltozott. Ha egy olyan tömbhöz adsz hozzá index nélküli elemet, amelyben a legnagyobb index értéke nagatív, az új elem indexe nulla (0) lesz. Azelőtt az új index a legnagyobb index + 1 lett úgyanúgy mint pozitív indexek esetén.

Ha `TRUE`-t adsz meg kulcsként az 1 egész típusú értéket fogja jelenteni, a `FALSE` pedig a 0-át. Ha kulcsként NULL-t adsz meg, üres stringként lesz értelmezve. Az üres string használata kulcsként létrehoz (vagy felülír) egy üres string kulcsot és az értéket; eltérően az üres szögletes zárójelektől.

Nem használhatsz tömböt vagy objektumot kulcsként. Ha mégis megpróbálod, egy Illegal offset type figyelmeztetést fogsz kapni.

### Létrehozás/módosítás a szögletes zárójeles formával

Meglévő tömbök is módosíthatóak konkrét értékek megadásával.

Ezt úgy tudod megtenni, hogy a tömb neve után szögletes zárójelekben megadod a kulcsot, amit módosítani szeretnél. Ha elhagyod a kulcsot, és csak egy üres szögletes zárójel párt ("[]") adsz meg a változó neve után, a tömb végére illeszthetsz elemet.

    $tomb[kulcs] = érték;
    $tomb[] = érték;
    // a kulcs lehet integer (egész szám) vagy string
    // az érték bármi lehet

Ha a $tomb nem létezik, ezzel létrejön. Tehát ez egy újabb alternatíva tömbök létrehozására. Ha módosítani szeretnél egy elemet, rendelj hozzá egy kulccsal azonosított elemhez egy új értéket. Ha meg szeretnél szüntetni egy kulcs/érték párt, használd az unset() függvényt.

`<?php $arr = array(5 => 1, 12 => 2); $arr[] = 56; // itt ez ugyanaz mint a $arr[13] = 56; $arr["x"] = 42; // Ez hozzáad egy új elemet // a tömbhöz "x" kulccsal unset($arr[5]); // Ez eltávolítja az elemet a tömbből unset($arr); // Ez az egész tömböt törli ?>`

> Megjegyzés: Mint ahogy fentebb említettük, ha a szögletes zárójelek között nem adsz meg kulcsot, akkor a létező indexek maxumuma + 1 lesz az új elem kulcsa. Ha még nincs egész index, akkor ez 0 (nulla) lesz. Ha olyan kulcsot adsz meg, amelyhez már van érték rendelve, az érték felül lesz írva.

> Figyelem
> Az indexgenerálás fent leírt algoritmusa PHP 4.3.0-tól megváltozott. Ha egy olyan tömbhöz adsz hozzá index nélküli elemet, amelyben a legnagyobb index értéke nagatív, az új elem indexe nulla (0) lesz. Azelőtt az új index a legnagyobb index + 1 lett úgyanúgy mint pozitív indexek esetén.

> Az automatikus indexeléshez használd legnagyobb szám nem kell abban a pillanatban létezzen a tömbben. Egyszerűen csak kellett valamikor létezett a tömbben a legutóbbi újraindexelés óta. A következő példa szemlélteti ezt:

> `<?php // Létrehozunk egy egyszerű tömböt $array = array(1, 2, 3, 4, 5); print_r($array); // Most kitörlünk minden elemet, de magát a tömböt nem foreach ($array as $i => $ertek) { unset($array[$i]); } print_r($array); // Hozzáadunk egy elemet (az új kulcs 5 lesz az elvárt 0 helyett) $array[] = 6; print_r($array); // Újraindexeljük: $array = array_values($array); $array[] = 7; print_r($array); ?>`

> A fenti példa a következő kimenetet adja:

>     Array
>     (
>         [0] => 1
>         [1] => 2
>         [2] => 3
>         [3] => 4
>         [4] => 5
>     )
>     Array
>     (
>     )
>     Array
>     (
>         [5] => 6
>     )
>     Array
>     (
>         [0] => 6
>         [1] => 7
>     )

## Hasznos függvények

Létezik néhámy függvény a tömbökkel való munka megkönnyítésére. Lásd a tömb függvények című részt.

> Megjegyzés: Az unset() függvénnyel lehet egy értéket a tömbből törölni. Figyelj arra, hogy a tömb nem lesz újraindexelve! Ha csak a "szokásos egész indexet" használod (nullától kezdve egyessével növelve), az újraindexelés hatását a array_values() függvénnyel érheted el.

> `<?php $a = array(1 => 'egy', 2 => 'kettő', 3 => 'három'); unset($a[2]); /* ennek eredményeképpen $a így fog kinézni: $a = array(1 => 'egy', 3 => 'három'); és NEM így: $a = array(1 => 'egy', 2 => 'három'); */ $b = array_values($a); // Itt a $b így néz ki: array(0 => 'egy', 1 => 'három'); ?>`

A foreach vezérlési szerkezet kifejezetten a tömbök számára jött létre. Egy egyszerű módszert ad tömbökön való végiglépkedésre.

## Mit tehetünk, és mit nem a tömbökkel

### Miért nem jó az $ize[bigyo] forma?

Minden string típusú kulcsot idézőjelek vagy aposztrófok közé kell tenni tömbbeli elemre történő hivatkozásnál, például: $ize['bigyo'] és nem $ize[bigyo]. Vajon miért nem jó $ize[bigyo] alak? Talán láttad ezt a szintaxist régi PHP programokban:

`<?php $ize[bigyo] = 'ellenség'; echo $ize[bigyo]; // stb. ?>`

Ez hibás, és mégis működik. Akkor mégis miért nem jó? Azért, mert a bigyo itt valójában egy nem definiált állandót jelöl, és nem a 'bigyo' sztringet (figyelj az aposztrófokra). A későbbi PHP verziókban már előfodulhatnak olyan előre definiált állandók, amelyeknek ugyanaz lesz a neve, mint ami a saját kódodban sztringként szerepel. Azért működik, mert ezeket a csupasz stringeket (idézőjel nélküli string, amelyeknek nem felel meg egy ismert szimbólum) a PHP a nevükkel azonos tartalmú sztringgé konvertálja. Például nincs definiálva `bigyo` nevű konstans, ezért a PHP helyettesíteni fogja a 'bigyo' stringgel.

> Megjegyzés: Ez nem azt jelenti, hogy mindig idézőjelek közé kellene raknod a kulcsot. Ne használj idézőjelet, amikor a kulcs konstans vagy változó, mivel ez megakadályozná a PHP-t abban hogy ezeket értelmezze.

> `<?php error_reporting(E_ALL); ini_set('display_errors', true); ini_set('html_errors', false); // Egyszerű tömb: $array = array(1, 2); $count = count($array); for ($i = 0; $i < $count; $i++) { echo "\n$i vizsgálata: \n"; echo "Rossz: " . $array['$i'] . "\n"; echo "Jó: " . $array[$i] . "\n"; echo "Rossz: {$array['$i']}\n"; echo "Jó: {$array[$i]}\n"; } ?>`

> Megjegyzés: A fenti példa a következő kimenetet adja:

>     0 vizsgálata:
>     Notice: Undefined index:  $i in /path/to/script.html on line 9
>     Rossz:
>     Jó: 1
>     Notice: Undefined index:  $i in /path/to/script.html on line 11
>     Rossz:
>     Jó: 1

>     1 vizsgálata:
>     Notice: Undefined index:  $i in /path/to/script.html on line 9
>     Rossz:
>     Jó: 2
>     Notice: Undefined index:  $i in /path/to/script.html on line 11
>     Rossz:
>     Jó: 2

Több példa ennek megmutatására:

`<?php
// Irassunk ki minden hibát
error_reporting(E_ALL);
$arr = array('gyümölcs' => 'alma', 'zöldség' => 'répa');
// Helyes
print $arr['gyümölcs']; // alma
print $arr['zöldség']; // répa
// Helytelen. Működik de E_NOTICE szintű hibát ad,
// mert nincs gyümölcs nevű konstans definiálva
//
// Notice: Use of undefined constant gyümölcs - assumed 'gyümölcs' in...
print $arr[gyümölcs]; // alma
// Definiáljunk egy konstanst, hogy lássuk mi folyik itt.
// A gyümölcs nevű konstanshoz a 'zöldség' értéket rendeljük.
define('gyümölcs', 'zöldség');
// Notice the difference now
print $arr['gyümölcs']; // alma
print $arr[gyümölcs]; // répa
// A következő rendben van, mert string belsejében van.
// A konstansokat nem keresi stringen belül, tehát itt nincs E_NOTICE
print "Hello $arr[gyümölcs]"; // Hello alma
// Kivétel: a stringben kapcsos zárójelekkel körülvett tömbök
// esetén figyeli a konstansokat
print "Hello {$arr[gyümölcs]}"; // Hello répa
print "Hello {$arr['gyümölcs']}"; // Hello alma
// Ez nem működik, szintaktikai hibát eredményez, mint például:
// Parse error: parse error, expecting T_STRING' or T_VARIABLE' or T_NUM_STRING'
// Ez természetesen szuperglobális tömbök esetén is érvényes.
print "Hello $arr['gyümölcs']";
print "Hello $_GET['ize']";
// Egy másik lehetőség az összefűzés (konkatenáció)
print "Hello " . $arr['gyümölcs']; // Hello alma
?>`

Ha beállítod az error_reporting()-ot hogy írja ki az `E_NOTICE` szintű hibákat (vagy ha `E_ALL`-ra állítod), akkor látni fogod ezeket a hibákat. Alapértelmezésben az error_reporting úgy van beállítva, hogy ezeket ne mutassa.

Ahogy a szintaxisról szóló részben tárgyaltuk, a szögletes zárójelek között ('[' and ']') kifejezés kell álljon. Ez azt jelenti, hogy írhatsz ilyeneket is:

`<?php echo $arr[fuggveny($bigyo)]; ?>`

Ez a példa bemutatja, hogyan használhatsz függvény visszatérési értéket tömbindexként. A PHP úgyszintén ismeri a konstansokat. Bizonyára hallottál már az E_* konstansokról.

`<?php $hiba_leiras[E_ERROR] = "Fatális hiba történt"; $hiba_leiras[E_WARNING] = "A PHP figyelmeztetést adott"; $hiba_leiras[E_NOTICE] = "Informális megjegyzés"; ?>`

Figyeld meg, hogy az E_ERROR egy érvényes azonosító, mint a valami az előző példában. De a legutóbbi példa ugyanaz, mintha ezt írnánk:

`<?php $hiba_leiras[1] = "Fatális hiba történt"; $hiba_leiras[2] = "A PHP figyelmeztetést adott"; $hiba_leiras[8] = "Informális megjegyzés"; ?>`

mivel az E_ERROR konstans értéke 1, stb.

As we already explained in the above examples, $ize[bigyo] still works but is wrong. It works, because bigyo is due to its syntax expected to be a constant expression. However, in this case no constant with the name bigyo exists. PHP now assumes that you meant bigyo literally, as the string "bigyo", but that you forgot to write the quotes.

#### De miért nem jó ez?

Valamikor a jövőben a PHP fejlesztői hozzáadhatnak egy új konstanst vagy kulcsszót a nyelvhez, vagy bevezethetsz egy új konstanst az alkalmazásodba, és akkor bajba kerülsz. Például jelenleg sem használhatóak az empty és default szavak, mivel ezek speciális kulcsszavak.

Ha ezek az érvek nem győznek meg: ez a szintaxis egyszerűen nem javasolt, és bármikor megszűnhet működni.

> Megjegyzés: Mint ahogy említettük, a dupla-idézőjelekkel megadott string-ben helyes, ha a tömbindexet nem veszed körül idézőjelekkel, így a "$ize[bigyo]" helyes. Részletekért lásd a fenti példákat, valamint a változók behelyettesítése című részt.

## Konverzió tömbbé

Ha az integer, float, string, boolean vagy resource típusokat konvertálod tömbbé (array), egyelemű tömböt kapsz eredményül (indexe 0), amely az eredeti elem értékét tartalmazza.

Ha objektumot konvertálsz tömbbé, a tömb elemei az objektum attribútumai lesznek, a kulcsok pedig a megfelelő attribűtumok nevei lesznek.

Ha a `NULL` értéket konvertálod tömbbé, üres tömböt kapsz eredményül.

## Tömbök összehasonlítása

Lehetőség van a tömbök összehasonlítására. Erre használhatod a array_diff() függvényt valamint a tömb operátorokat.

## Példák

A tömb típus a PHP-ben nagyon sokoldalú, ezért összegyűjtöttünk néhány példát, hogy megmutassuk a tömbök erejét.

`<?php
// ez
$a = array( 'szín' => 'piros',
'íz' => 'édes',
'alak' => 'kerek',
'név' => 'alma',
4 // 0 lesz a kulcsa
);
// teljesen megyezik ezzel
$a['szín'] = 'piros';
$a['íz'] = 'édes';
$a['alak'] = 'kerek';
$a['név'] = 'alma';
$a[] = 4; // 0 lesz a kulcsa
$b[] = 'a';
$b[] = 'b';
$b[] = 'c';
// a következő tömböt adja: array(0 => 'a', 1 => 'b', 2 => 'c')
// vagy egyszerűen: array('a', 'b', 'c')
?>`

Példa 11-6. Az array() használata

`<?php
// Tömb, mint tulajdonság hozzárendelés
$map = array( 'verzió' => 4,
'rendszer' => 'Linux',
'nyelv' => 'angol',
'short_tags' => true
);
// szigorúan számokat tartalmazó tömb
$tomb = array( 7,
8,
0,
156,
-10
);
// ez ugyanaz, mint array (0 => 7, 1 => 8, ...)
$valtogatas = array( 10, // 0. indexű/kulcsú
5 => 6,
3 => 7,
'a' => 4,
11, // kulcsa 6 (a legnagyobb egész kulcs 5 volt)
'8' => 2, // kulcsa 8 (egész!)
'02' => 77, // kulcsa '02'
0 => 12 // a 10 értéket felülírjuk 12-vel
);
// üres tömb
$ures = array();
?>`

Példa 11-7. Kollekció

`<?php $szinek = array('piros', 'kék', 'zöld', 'sárga'); foreach ($szinek as $szin) { echo "Szereted a(z) $szin színt?\n"; } ?>`

A fenti példa a következő kimenetet adja:

    Szereted a(z) piros színt?
    Szereted a(z) kék színt?
    Szereted a(z) zöld színt?
    Szereted a(z) sárga színt?

Figyelj arra, hogy jelenleg közvetlenül nem lehet módosítani a tömb elemeinek értékét ezzel a ciklussal. A problémát a következőképpen tudod megkerülni:

Példa 11-8. Kollekció

`<?php foreach ($szinek as $kulcs => $szin) { // nem működik (nem módosítja a tömböt): //$szin = strtoupper($szin); // működik (módosítja a tömböt): $szinek[$kulcs] = strtoupper($szin); } print_r($szinek); ?>`

A fenti példa a következő kimenetet adja:

    Array
    (
        [0] => PIROS
        [1] => KÉK
        [2] => ZÖLD
        [3] => SÁRGA
    )

Ebben a példában egy egytől számozott tömböt készítünk.

Példa 11-9. Egytől kezdődő index

`<?php $elsonegyed = array(1 => 'Január', 'Február', 'Március'); print_r($elsonegyed); ?>`

A fenti példa a következő kimenetet adja:

    Array
    (
        [1] => 'Január'
        [2] => 'Február'
        [3] => 'Március'
    )

Példa 11-10. Tömb feltöltése

`<?php // egy tömb felöltése a <link linkend="ref.dir">könyvtárban</link> található filenevekkel $konyvtar = opendir('.'); while (false !== ($filenev = readdir($konyvtar))) { $filenevek[] = $filenev; } closedir($konyvtar); ?>`

A tömbök rendezettek. A sorrendet számos függvénnyel megváltoztathatod. Lásd a tömb függvények című részt további információkért. A tömbben szereplő elemek számát a count() függvénnyel tudod lekérdezni.

Példa 11-11. Tömbök rendezése

`<?php sort($filenevek); print_r($filenevek); ?>`

Mivel a tömb egy értéke bármi lehet, értékként akár egy másik tömböt is megadhatsz. Ilyen formában készíthetsz rekurzív vagy többdimenziós tömböket.

Példa 11-12. Rekurzív és többdimenziós tömbök

`<?php
$gyumolcsok = array("gyümölcsök" => array("a" => "narancs",
"b" => "banán",
"c" => "alma"
),
"számok" => array (1,
2,
3,
4,
5,
6
),
"lyukak" => array ( "első",
5 => "második",
"harmadik"
)
);
// Néhány példa a fenti tömb elemeinek hivatkozására
echo $gyumolcsok["lyukak"][5]; // kiírja, hogy "második"
echo $gyumolcsok["gyümölcsök"]["a"]; // kiírja, hogy "narancs"
unset($gyumolcsok["lyukak"][0]); // eltávolítja az "első"-t
// Készítünk egy új többdimenziós tömböt
$gyumolcsle["alma"]["zöld"] = "finom";
?>`

Jegyezd meg, hogy tömb értékül adása mindig másolást jelent. Használd a referencia operátort, ha a tömböt referencia szerint szeretnéd átadni.

`<?php $arr1 = array(2, 3); $arr2 = $arr1; $arr2[] = 4; // az $arr2 megváltozott, // az $arr1 még mindig array(2, 3) $arr3 = &$arr1; $arr3[] = 4; // itt az $arr1 és az $arr3 megegyeznek ?>`

Előző | Tartalom | Következő
Stringek | Fel | Objektumok