Osztályok, objektumok (PHP 4-ben)
Table of Contents
- extends
- Konstruktor
- Hatókör megadó operátor (::)
- parent
- Objektumok szerializációja, objektumok session-ökben
- A speciális __sleep és __wakeup metódusok
- Referenciák a konstruktorban
- Objektuok összehasonlítása
class
Az osztály (objektumtípus) változók és rajtuk műveletet végző függvények [metódusok] együttese. Osztályt az alábbi szintakszis szerint lehet definiálni:
<?php
class Kosar {
var $dolgok; // A kosárban levő dolgok
// berak a kosárba $db darabot az $sorsz indexű dologból
function berak($sorsz, $db) {
$this->dolgok[$sorsz] += $db;
}
// kivesz a kosárból $db darabot az $sorsz indexű dologból
function kivesz($sorsz, $db) {
if ($this->dolgok[$sorsz] > $db) {
$this->dolgok[$sorsz] -= $db;
return true;
} elseif ($this->dolgok[$sorsz] == $db) {
unset($this->dolgok[$sorsz]);
return true;
} else {
return false;
}
}
}
?>
Ez definiál egy Kosar nevű osztályt, ami a kosárban levő áruk asszociatív tömbjéből áll, és definiál 2 funkciót hozzá, hogy bele lehessen rakni, illetve kivenni a kosárból.
Egy osztálydefiníciót NEM szedhetsz szét több fájlra. Szintén NEM darabolhatsz egy osztálydefiníciót több PHP blokkra, hacsak nem egy metódus közepén teszed ezt valamilyen oknál fogva. A következő példakód tehát működésképtelen:
<?php
class teszt {
<?php
?>
function teszt() {
print 'oké';
}
}
?>
Ez viszont rendben van:
<?php
class teszt {
function teszt() {
?>
<?php
print 'oké';
}
}
?>
Az alábbi figyelmeztetések a PHP 4-es verziójára érvényesek.
Az stdClass név le van foglalva, mivel belsőleg a Zend motor használja. Emiatt nem lehet egy stdClass nevű osztályod PHP-ben.
A __sleep és __wakeup nevek speciálisak a PHP osztályokban. Nem szabad ezeket a neveket használni a metódusokhoz, hacsak nem a hozzájuk tartozó speciális funkcionalitást szeretnéd felülírni. Lásd az alábbi részletes leírást.
A PHP számára lefoglalt az összes __ karakterekkel kezdődő metódusnév, mint speciális név. Nem szabad __ karakterekkel kezdődő metódusnevet adni, hacsak nem a dokumentált funkciókat szeretnéd használni.
PHP 4-ben csak állandó értékű var inicializáló értékek megengedettek. Ha nem állandó értéket szeretnél beállítani, írnod kell egy inicializáló metódust, ami automatikusan meghívódik, amikor egy objektumpéldány létrejön az osztályból. Az ilyen metódusokat hívjuk konstruktoroknak (lásd lentebb).
class Kosar {
/* Egyik alábbi értékadás sem működik PHP 4-ben */
var $mai_datum = date("Y. m. d.");
var $nev = $csaladi_nev;
var $tulajdonos = 'Ferenc ' . 'János';
/* Ámde tömböt konstans elemekkel megadhatunk */
var $termekek = array("Videó", "TV");
}
/* Így kell a fenti beállításokat elérni */
class Kosar {
var $mai_datum;
var $nev;
var $tulajdonos;
var $termekek = array("Videó", "TV");
function Kosar() {
$this->mai_nap = date("Y. m. d.");
$this->nev = $GLOBALS['csaladi_nev'];
/* stb. . . */
}
}
?>
Az osztályok típusok, vagyis az aktuális változók tervrajzai. A kívánt típusú változót a new operátorral hozhatod létre.
<?php
$kosar = new Kosar;
$kosar->berak("10", 1);
$masik_kosar = new Kosar;
$masik_kosar->berak("0815", 3);
?>
Ez létrehozza a Kosar objektumosztály $kosar és $masik_kosar nevű objektumpéldányait. A $kosar objektum berak() függvényét meghívtuk, hogy a 10-es számú árucikkből rakjon 1 darabot a kosárba. Három darab 0815 számú ternék került a $masik_kosar nevű kosárba.
Mind a $kosar, mind a $masik_kosar objektumoknak megvannak a berak() és kivesz() metódusai, és tulajdonságai. Ezek azonban egymástól független metódusok és tulajdonságok. Az objektumokról hasonlóan gondolkozhatsz, mint a könyvtárakról az állományrendszerben. Lehetséges, hogy két különböző OLVASSEL.TXT állományod van, ha ezek két különböző könyvtárban vannak. Úgy mint a könytáraknál, ahol meg kell adnod a teljes elérési utat, hogy egy állományra szeretnél hivatkozni a gyökérkönyvtárban, a teljes metódusnevet meg kell adnod, hogy meg tudd azt hívni. A PHP nyelvben a gyökérkönyvtár analógiája a globális környezet, és az elérési út elválasztója a ->. Ezért a $kosar->dolgok név és a $masik_kosar->dolgok név két különböző változót ad meg. Figyeld meg, hogy a változót $kosar->dolgok néven kell elérni, és nem $kosar->$dolgok néven, azaz a PHP változók neveibe csak egy dollárjelet kell tenned.
<?php
// helyes, egy dollárjel
$kosar->dolgok = array("10" => 1);
// helytelen, mivel a $kosar->$dolgok értelme $kosar->""
$kosar->$dolgok = array("10" => 1);
// helyes, de lehetséges, hogy nem a megcélzott eredmény
// $kosar->$valtozo értelme $kosar->dolgok
$valtozo = dolgok;
$kosar->$valtozo = array("10" => 1);
?>
Egy osztály definiálásakor nem tudhatod, milyen néven lesz majd elérhető az objektumod a PHP programban: a Kosar osztály készítése idején nem volt ismert, hogy később $kosar vagy $masik_kosar néven nevezzük-e majd az objektumpéldányt. Ezért nem használhatod a Kosar osztályban a $kosar->dolgok hivatkozást. De hogy el tudjad érni az osztály saját metódusait és tulajdonságait az objektumpéldány nevétől függetlenül, használhatod a $this kvázi-változót, amit 'a sajátom' vagy 'az aktuális objektumpéldány' értelemben alkalmazhatsz. Ezért a '$this->dolgok[$sorsz] += $db' úgy olvasható, hogy 'adj $db darab $sorsz sorszámú terméket a saját dolgok tömbömhöz', vagy 'adj $db darab $sorsz sorszámú terméket az aktuális objektumpéldány dolgok tömbjéhez'.
Note: A $this néven futó kvázi-változó statikusan hívott osztálymetódusok esetében nincs jelen. Ez alól kivétel az az eset, amikor statikusan hívjuk meg a metódust egy példányosított objektumon belülről. Ez esetben a $this a meghívó objektumra fog hivatkozni. Ezt mutatja be szemléletesebben az alábbi példa:
<?php
class A {
function ize() {
if (isset($this)) {
echo '$this definiálva van (';
echo get_class($this);
echo ")\n";
} else {
echo "\$this nincs definiálva.\n";
}
}
}
class B {
function bigyo() {
A::ize();
}
}
$a = new A();
$a->ize();
A::ize();
$a = new B();
$b->bigyo();
B::bigyo();
?>A fenti példa a következő kimenetet adja:
$this definiálva van (a) $this nincs definiálva. $this definiálva van (b) $this nincs definiálva.
Note: Van pár hasznos függvény az osztályok és objektumok kezeléséhez. Lásd az Osztály és objektum függvények című részt.