goba Mon Aug 20 12:29:57 2001 EDT Modified files: /phpdoc/hu Translators /phpdoc/hu/functions outcontrol.xml /phpdoc/hu/language oop.xml Log: Correcting one make error in outcontrol.xml Adding the updated version of oop.xml, now it is actual
Index: phpdoc/hu/Translators diff -u phpdoc/hu/Translators:1.51 phpdoc/hu/Translators:1.52 --- phpdoc/hu/Translators:1.51 Mon Aug 20 11:36:05 2001 +++ phpdoc/hu/Translators Mon Aug 20 12:29:56 2001 @@ -185,7 +185,7 @@ control-structures.xml Kontra Gergely 1.37 expressions.xml Kontra Gergely 1.13 functions.xml Kontra Gergely 1.16 -oop.xml Kontra Gergely 1.5 ++ +oop.xml Kontra Gergely 1.26 operators.xml Kontra Gergely 1.26 references.xml Hojtsy Gábor 1.15 types.xml Hojtsy Gábor 1.47 Index: phpdoc/hu/functions/outcontrol.xml diff -u phpdoc/hu/functions/outcontrol.xml:1.3 phpdoc/hu/functions/outcontrol.xml:1.4 --- phpdoc/hu/functions/outcontrol.xml:1.3 Mon Aug 20 11:35:41 2001 +++ phpdoc/hu/functions/outcontrol.xml Mon Aug 20 12:29:56 2001 @@ -39,7 +39,7 @@ </para> <para> A fenti példában az echo által generált szöveg a pufferben - várakozik mindaddig, amíg egy <function>ob_end_flush</function + várakozik mindaddig, amíg egy <function>ob_end_flush</function> parancs nem érkezik. Mindeközben a <function>setcookie</function> által generált fejlécsor minden hiba nélül elmegy a böngésző felé (ez amúgy lehetetlen volna, mivel az echo már a webszerver Index: phpdoc/hu/language/oop.xml diff -u phpdoc/hu/language/oop.xml:1.3 phpdoc/hu/language/oop.xml:1.4 --- phpdoc/hu/language/oop.xml:1.3 Sun Aug 19 10:21:30 2001 +++ phpdoc/hu/language/oop.xml Mon Aug 20 12:29:56 2001 @@ -13,18 +13,21 @@ <programlisting role="php"> <![CDATA[ <?php -class Kosar { +class Kosar +{ var $dolgok; // A kosárban levő dolgok // berak a kosárba $db darabot az $sorsz indexű dologból - function berak ($sorsz, $db) { + function berak ($sorsz, $db) + { $this->dolgok[$sorsz] += $db; } // kivesz a kosárból $db darabot az $sorsz indexű dologból - function kivesz ($sorsz, $db) { + function kivesz ($sorsz, $db) + { if ($this->items[$sorsz] > $db) { $this->items[$sorsz] -= $db; return true; @@ -44,45 +47,182 @@ asszociatív tömbjéből áll, és definiál 2 funkciót hozzá, hogy bele lehessen rakni, illetve kivenni a kosárból. </para> - <note><simpara> - PHP 4-ben csak konstans <literal>var</literal> inicializáló - értékek megengedettek. Használd a konstruktort nem konstans - értékű inicializáláshoz. - </simpara></note> + + <caution> + <simpara> + Az alábbi figyelmeztetések a PHP 4-es verziójára érvényesek. + </simpara> + + <simpara> + Az <literal>stdClass</literal> név le van foglalva, mivel + belsőleg a Zend motor használja. Emiatt nem lehet egy + <literal>stdClass</literal> nevű osztályod PHP-ben. + </simpara> + + <simpara> + A <literal>__sleep</literal> és <literal>__wakeup</literal> + 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. + </simpara> + + <simpara> + A PHP fenntartja az összes __ karakterekkel kezdődő + metódusnevet, mint speciális neveket. Nem szabad + __ karakterekkel kezdődő metódusnevet adni, hacsak nem + a dokumentált funkciókat szeretnéd használni. + </simpara> + </caution> + + <note> + <simpara> + PHP 4-ben csak állandó értékű <literal>var</literal> + 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). + </simpara> + <informalexample> + <programlisting role="php"> +<![CDATA[ +/* Egyik alábbi értékadás sem működik PHP 4-ben */ +class Kosar +{ + var $mai_datum = date("Y. m. d."); + var $nev = $csaladi_nev; + var $tulajdonos = 'Ferenc ' . 'János'; + 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; + + function Kosar() + { + $this->mai_nap = date("Y. m. d."); + $this->nev = $GLOBALS['csaladi_nev']; + /* stb. . . */ + } +} +]]> + </programlisting> + </informalexample> + </note> + + <para> 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. + A kívánt típusú változót a <literal>new</literal> operátorral + hozhatod létre. </para> <informalexample> <programlisting role="php"> <![CDATA[ - $kosar = new Kosar; - $kosar->berak("10", 1); +$kosar = new Kosar; +$kosar->berak("10", 1); + +$masik_kosar = new Kosar; +$masik_kosar->berak("0815", 3); ]]> </programlisting> </informalexample> <para> - Ez létrehozza a Kosar objektumosztály $kosar nevű objektumpéldányát. - Az objektum berak() függvényét meghívtuk, hogy a 10-es számú árucikkből - rakjon 1 darabot a kosárba. + 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. </para> - <para> - Osztályok származhatnak más osztályoktól is (öröklés). - A leszármazott osztály az ős minden változóját és függvényét - [metódusát] örökli. Erre használható az extends kulcsszó. - A többszörös öröklés nem támogatott [:( vagyis egy gyereknek több őst nem - nevezhetünk meg. A tranzitív öröklés azonban megengedett]. + <para> + Mind a $kosar, mind a $masik_kosar objektumoknak megvannak + a break() és kivesz() metódusai, és tulajdonságai. Ezek + azonban egymástól független metódusk é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 neveiben + csak egy dollárjelet kell tenned. + </para> + <informalexample> + <programlisting role="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); + </programlisting> + </informalexample> + <para> + 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 írhatod a Kosar + osztályban, hogy $kosar->dolgok. De hogy el tudjad érni az + osztály saját metódusait és tulajdonságait az objektumpéldány(ok) + 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'. + </para> + </sect1> + + <sect1 id="keyword.extends"> + <title><literal>extends</literal></title> + + <para> + Gyakran szeretnél olyan osztályokat kialakítani, amelyek + hasonló tulajdonságokkal és metódusokkal rendelkeznek, + mint egy már meglévő osztály. Tulajdonképpen jó gyakorlat + egy általános osztályt definiálni, amit minden projektedben + használhatsz, és ezt az osztályt alakítani az egyes + projektek igényeinek megfelelően. Ennek a megvalósítása + érdekében az osztályok lehetnek más osztályok kiterjesztései. + A kietrejesztett, vagy származtatott osztály minden + tulajdonággal és metódussal rendelkezik, ami a kiindulási + osztályban megvolt (ezt nevezzük öröklésnek, bár senki + sem hal meg a folyamat során). Amit hozzáadsz a kiindulási + osztályhoz, azt nevezzük kiterjesztésnek. Nem lehetséges + megcsonkítani egy osztályt, azaz megszüntetni egy metódust, + vagy tulajdonságot. Egy leszármazott osztály mindig pontosan + egy alaposztálytól függ, azaz egyidejűéleg többszörös + leszármaztatás nem támogatott. A kiterjesztés kulcsszava az + 'extends'. </para> <informalexample> <programlisting role="php"> <![CDATA[ -class Gazdas_Kosar extends Kosar { +class Gazdas_Kosar extends Kosar +{ var $tulaj; - function tulajdonosa ($nev) { + function tulajdonosa ($nev) + { $this->tulaj = $nev; } } @@ -110,24 +250,35 @@ ]]> </programlisting> </informalexample> + </sect1> - <para> - Osztályok függvényein belül a $this a manipulálandó objektumpéldányt jelenti. - A $this->valami formát kell használnod az aktuális objektum valami nevű - változó vagy metódus elérésére. - </para> + <sect1 id="language.oop.constructor"> + <title><literal>Constructors</literal></title> + + <caution> + <simpara> + A PHP 3 és PHP 4 konstruktorok különbözőképpen működnek. + A PHP 4 megvalósítása erősen javasolt. + </simpara> + </caution> <para> A konstruktorok olyan az osztályok olyan metódusai, amelyek - automatikusan meghívódnak, amikor létrehozol egy új objektumpéldányt. - Egy függvény [metódus] úgy lesz konstruktor, ha a neve megegyezik - az osztály nevével. + automatikusan meghívódnak, amikor létrehozol egy új objektumpéldányt + a <literal>new</literal> kulcsszóval. A PHP 3-ban egy metódus + úgy válik konstruktorrá, hogy a neve megyezik az osztály nevével. + A PHP 4-ben egy metódus úgy lesz kostruktorrá, hogy a neve + megegyezik annak az osztálynak a nevével, ahol deifiniálták. + A különbség hajszálnyi, de kritikus (lásd lentebb). </para> <informalexample> <programlisting role="php"> <![CDATA[ -class Auto_Kosar extends Kosar { - function Auto_Kosar () { +// A PHP 3 és PHP 4 verziókban is működik +class Auto_Kosar extends Kosar +{ + function Auto_Kosar () + { $this->berak ("10", 1); } } @@ -141,21 +292,25 @@ a kosarat 1 darab "10"-es áruval, valahányszor a new operátorral hozzuk létre az objektumot. [de csak akkor!!!] A konstruktoroknak is lehetnek paramétereik, és ezek lehetnek opcionálisak, ami még - hasznosabbá teszi őket. + hasznosabbá teszi őket. Ha paraméterek nálkül is használható osztályt + szeretnél, állíts be minden paraméternek alapértéket. </para> <informalexample> <programlisting role="php"> <![CDATA[ -class Konstruktoros_Kosar extends Kosar { - function Konstruktoros_Kosar ($sorsz = "10", $db = 1) { +// A PHP 3 és PHP 4 verziókban is működik +class Konstruktoros_Kosar extends Kosar +{ + function Konstruktoros_Kosar ($sorsz = "10", $db = 1) + { $this->berak ($sorsz, $db); } } // Mindig ugyanazt az uncsi dolgot veszi... -$kiindulo_kosar = new Konstruktoros_Kosar; +$kiindulo_kosar = new Konstruktoros_Kosar; // Igazi vásárlás @@ -166,13 +321,608 @@ <caution> <simpara> - A leszármaztatott osztályokban a szülő osztály konstruktora - <emphasis>NEM</emphasis> hívódik meg automatikusan, amikor - a származtatott osztály konstruktorát meghívod. - </simpara> + A PHP 3-ban a leszármazott osztályokra és konstrukrotokra + számos korlátozás van. Az alábbi példákat érdemes alaposan + áttekinteni, hogy megértsd ezeket a korlátozásokat. + </simpara> + </caution> + + <informalexample> + <programlisting role="php"> +<![CDATA[ +class A +{ + function A() + { + echo "Én vagyok az A osztály konstruktora.<br>\n"; + } +} + +class B extends A +{ + function C() + { + echo "Én egy metódus vagyok.<br>\n"; + } +} + +// PHP 3-ban semmilyen konstruktor sem kerül meghívásra +$b = new B; +]]> + </programlisting> + </informalexample> + + <para> + PHP 3-ban semmilyen konstruktor sem kerül meghívásra + a fenti példában. A PHP 3 szabálya a következő: + 'A konstruktor egy metódus, aminek ugyanaz a neve, + mint az osztálynak'. Az osztály neve B, és nincs B() + nevű metódus a B osztályban. Semmi sem történik. + </para> + + <para> + Ez a PHP 4-ben ki van javítva egy másik szabály bevezetésével: + Ha az osztályban nincs konstruktor, a szülő osztály konstruktora + hívódik meg, ha létezik. A fenti példa kimenete 'Én vagyok az A + osztály konstruktora.<br>' lett volna PHP 4-ben. + </para> + + <informalexample> + <programlisting role="php"> +<![CDATA[ +class A +{ + function A() + { + echo "Én vagyok az A osztály konstruktora.<br>\n"; + } + + function B() + { + echo "Én egy B nevű metódus vagyok az A osztályban.<br>\n"; + echo "Nem vagyok A konstruktora.<br>\n"; + } +} + +class B extends A +{ + function C() + { + echo "Én egy metódus vagyok.<br>\n"; + } +} + +// Ez meghívja B()-t, mint konstruktort +$b = new B; +]]> + </programlisting> + </informalexample> + + <para> + A PHP 3-ban az A osztály B() metódusa hirtelen konstruktorrá + válik a B osztályban, habár soha sem volt ez a célunk. + A PHP 3 szabálya: 'A konstruktor egy metódus, aminek ugyanaz + a neve, mint az osztálynak'. A PHP 3 nem foglalkozik azzal, + hogy a metódus a B osztályban van-e definiálva, vagy öröklés + útján áll rendelkezésre. + </para> + + <para> + Ez a PHP 4-ben ki van javítva egy másik szabály bevezetésével: + 'A konstruktor egy metódus, aminek ugyanaz a neve, mint + az osztálynak, ahol deifiniálták'. Ezért a PHP 4-ben a B + osztálynak nincs saját konstruktora, így a szülő osztály + kostruktora hívódik meg, kiírva, hogy 'Én vagyok az A + osztály konstruktora.<br>'. + </para> + + <caution> + <simpara> + Sem a PHP 3, sem a PHP 4 nem hívja meg a szülő osztály + konstruktorát automatikusan egy leszármazott osztály + definiált konstruktorából. A te feladatod, hogy meghívd + a szülő konstruktorát, ha szükséges. + </simpara> + </caution> + + <note> + <simpara> + Nem léteznek destruktorok sem a PHP 3 sem a PHP 4 + verzióiban. Bár használhatod a + <function>register_shutdown_function</function> + függvényt a destruktorok legtöbb viselkedésének + eléréséhez. + </simpara> + </note> + + <para> + A destruktor olyan metódus, ami automatikusan + meghívódik, amikor egy objektum megszűnik, akár + az <function>unset</function> meghívásával, akár + a környezete megszűnése miatt. PHP-ben nincsenek + destruktorok. + </para> + </sect1> + + <sect1 id="keyword.paamayim_nekudotayim"> + <title><literal>::</literal></title> + + <caution> + <simpara> + Az alábbiak csak PHP 4-ben érvényesek. + </simpara> </caution> + + <para> + Időnként hasznos az ősök metódusaira vagy tulajdonádaira + hivatkozni, vagy olyan osztály metódusokat meghívni, amik + nem példányosult objektumokhoz tartoznak. A :: operátor + erre használható. + </para> + + <informalexample> + <programlisting role="php"> +<![CDATA[ +class A +{ + function pelda() + { + echo "Én az eredeti A::pelda() metódus vagyok.<br>\n"; + } +} + +class B extends A +{ + function pelda() + { + echo "Én a felüldefiniáló B::pelda() metódus vagyok.<br>\n"; + A::example(); + } +} + +// nincs semmilyen objektum az A osztályból +// ez azonban ki fogja írni: +// Én az eredeti A::pelda() metódus vagyok.<br> +A::pelda(); + +// B egy objektuát hozzuk létre +$b = new B; + +// ez ki fogja írni: +// Én a felüldefiniáló B::pelda() metódus vagyok.<br> +// Én az eredeti A::pelda() metódus vagyok.<br> +$b->pelda(); +]]> + </programlisting> + </informalexample> + + <para> + A fenti példa meghívja a pelda() metódusát az + A osztálynak, habár nincs konkrét példányunk az + A osztályból, tehát nem írhatnánk azt, hogy + $a->pelda(), vagy valami hasonlót. Ehelyett a + pelda() egy 'osztály metódusként' viselkedik, + azaz az osztály egy függvényeként, és nem + egy példány metódusaként. + </para> + + <para> + Osztály függvények léteznek, de osztály tulajdonságok + (változók) nem. Mivel a hívás pillanatában semmilyen + objektum nem létezik, egy osztály metódus nem használhat + objektum változókat, és egyáltalán nem használhatja a $this + speciális referenciát. Egy objektum metódus azonban + természetesen dolgozhat globális változókkal és lokális + változókkal is. + </para> + + <para> + A fenti példában a B osztály felüldefiniálja a pelda() + metódust. Az eredeti definíció az A osztályból eltűnik, + és nem érhető el többé, hacsak nem az A osztályban + megvalósított pelda() függvényre hivatkozol közvetlenül, + a :: operátor segítségével. Írj A::pelda()-t, hogy + elérd ezt a hatást (ebben az esetben írhatnál + parent::pelda()-t is, ahogy a következő bekezdésekben + olvasható). + </para> + + <para> + Ebben a környezetben van egy aktuálisan használt objektum, + és ennek lehetnek objektum változói (tulajdonságai). + Ezért ha egy objektum függvényen belül használod ezt + az operátort, alkalmazhatod a $this-t, és az objektum + tulajdonságokat. + </para> </sect1> + + <sect1 id="keyword.parent"> + <title><literal>parent</literal></title> + + <para> + Gyakran van szükség arra, hogy a szülő tulajdonságaira, + vagy metódusaira hivatkozzunk leszármazott osztályokban. + Ez különösen igaz, ha a leszármazott osztály egy + finomítása, vagy specializálása az alaposztálynak. + </para> + + <para> + Ahelyett, hogy a szülő osztály nevét megadd minden ilyen + meghíváskor (mint a hogy a :: operátor példája mutatta), + használhatod a <literal>parent</literal> speciális nevet, + ami tulajdonképpen a szülő osztály nevét jelenti, amit + az <literal>extends</literal> kulcsszónál megadtál. Ennek + a speciális névnek a használatával elkerülöd a szülő + osztály nevének ismétlődését. Ha a megvalósítás során + a leszármazási fát meg kell változtatni, csak egy helyen, + az <literal>extends</literal> kulcsszónál kell átírnod + a nevet. + </para> + + <informalexample> + <programlisting role="php"> +<![CDATA[ +class A +{ + function pelda() + { + echo "Én A::pelda() vagyok egyszerű funkcióval.<br>\n"; + } +} + +class B extends A +{ + function pelda() + { + echo "Én B::pelda() vagyok több funkcióval.<br>\n"; + parent::pelda(); + } +} + +$b = new B; + +// Ez a B::pelda() metódust hívja, ami az A::pelda()-t hívja +$b->pelda(); +]]> + </programlisting> + </informalexample> + </sect1> + + <sect1 id="language.oop.serialization"> + <title>Objektumok szerializációja, objektumok session-ökben</title> + + <note> + <simpara> + A PHP 3-ban az objektumok elveszítik az osztály-hozzárendelésüket + a szerializációs, és deszerializációs folyamat során. Az eredmény + objektum típusú, de nem tartozik semelyik osztályhoz, és nincs + egy metódusa sem, tehát eléggé használhatatlan (csupán egy + tömb, furcsa szintakszissal). + </simpara> + </note> + + <caution> + <simpara> + A következő információk csak a PHP 4-es változatára érvényesek. + </simpara> + </caution> + + <para> + A <function>serialize</function> egy karaktersorozatot + ad vissza, ami az átadott érték byte-sorozatban megadott + megfelelője. Az <function>unserialize</function> + alakít vissza egy ilyen karaktersorozatot az eredeti + értékké. A szerializációs folyamat során egy objektum + átadásával elmenthetjük az objektum minden tulajdonságát + (változóját). A függvények nem kerülnek elmentésre, + csak az osztály neve. + </para> + + <para> + Ahhoz, hogy az <function>unserialize</function> segítségével + vissza tudj állítani egy objektumot, az objektum osztályának + definiálva kell lennie. Azaz, ha van egy $a objektumod + (az A osztályból), az elso.php oldalon, és ezt szerializálod, + kapsz egy karaktersorozatot, ami az A osztályra hivatkozik, + és tartalmazza az összes $a-ban lévő változó (tulajdonság) + értékét. Ha ezt a karaktersorozatot a masodik.php oldalon + objektummá szeretnéd alakítani, újra létrehozva az A osztály + $a nevű objektumát, az A osztály definíciója rendelkezésre + kell, hogy álljon a masodik.php oldalon is. Ez úgy érhető + el, hogy az A osztály definícióját egy külső állományban + tárolod, és ezt alkalmazod mind az elso.php, mind a masodik.php + oldalon. + </para> + + <informalexample> + <programlisting role="php"> +<![CDATA[ +aosztaly.inc: + class A + { + var $egy = 1; + + function egyet_mutat() + { + echo $this->egy; + } + } + +elso.php: + include("aosztaly.inc"); + + $a = new A; + $s = serialize($a); + // tároljuk az $s-t valahol, ahol masodik.php megtalálja + $fp = fopen("tarolas", "w"); + fputs($fp, $s); + fclose($fp); + +masodik.php: + // ez szükséges, hogy a deszerializáció rendben legyen + include("aosztaly.inc"); + + $s = implode("", @file("tarolas")); + $a = unserialize($s); + + // most már használható az egyet_mutat() metódus + $a->egyet_mutat(); +]]> + </programlisting> + </informalexample> + + <para> + Ha session-öket alkalmazol, és a <function>session_register</function> + függvénnyel regisztálsz objektumokat, ezek az objektumok + automatikusan szerializálódnak minden PHP program futása + után, és deszerializálódnak minden további programban. Ez + egyszerűen azt jelenti, hogy ezek az objektumok akármelyik + oldalon feltűnhetnek, miután a session részévé váltak. + </para> + + <para> + Erősen javasolt, hogy minden regisztrált objektum + osztály definícióját betöltsd minden oldalon, még + akkor is, ha éppen nem használod azokat. Ha ezt nem + teszed meg, és egy objektum úgy deszerializálódik, + hogy nem áll rendelkezésre az osztály definícója, + el fogja veszteni az osztály hozzárendelését, és + az <literal>stdClass</literal> osztály egy példánya + lesz, metódusok nélkül, így használhatatlanná válik. + </para> + + <para> + Ezért ha a fenti példában az $a a session részévé + válik a <literal>session_register("a")</literal> hívással, + be kell töltened az <literal>aosztaly.inc</literal> + külső állományt minden oldalon, és nem csak az elso.php + és masodik.php programokban. + </para> + </sect1> + + <sect1 id="language.oop.magic-functions"> + <title>A speciális <literal>__sleep</literal> és <literal>__wakeup</literal> +metódusok</title> + + <para> + A <function>serialize</function> ellenőrzi, hogy van-e az + osztályodnak <literal>__sleep</literal> nevű metódusa. Ha van, + ez lefut a szerializáció előtt. Ez megtisztíthatja az objektumot, + és végül egy tömbbel tér vissza, ami tartalmazza azon tulajdonságok + neveit, amik az objektummal kapcsolatban szerializálásra kerülnek. + </para> + + <para> + A <literal>__sleep</literal> célja, hogy bezárjon minden + adatbázis kapcsolatot, a várakozó adatokat lementse, és + hasonló 'tisztító' jellegű tevékenységeket végezzen. Akkor + is hasznos lehet, ha nagyon nagy objektumaid vannak, amiket + külön szeretnél lementeni. + </para> + + <para> + Ezzel szemben az <function>unserialize</function> a speciális + <literal>__wakeup</literal> nevű függvényt használja. Ha ez + létezik, ez a függvény alkalmazható arra, hogy visszaállítsa + az objektum erőforrásait. + </para> + + <para> + A <literal>__wakeup</literal> célja lehet például, + hogy visszaállítson egy adatbázis kapcsolatot, ami + a szerializáció során elveszett, és hasonló beállítási + feladatokat végezzen. + </para> + </sect1> + + <sect1 id="language.oop.newref"> + <title>Referenciák a konstruktorban</title> + <para> + Referenciák képzése kontruktorokban problémás helyzetekhez + vezethet. Ez a leírás segít a bajok elkerülésében. + <informalexample> + <programlisting role="php"> +<![CDATA[ +class Ize +{ + function Ize($nev) + { + // egy referencia létrehozása a globális $globalref változóban + global $globalref; + $globalref[] = &$this; + // a név beállítása a kapott értékre + $this->nevBeallitas($nev); + // és kiírás + $this->nevKiiras(); + } + + function nevKiiras() + { + echo "<br>",$this->nev; + } + + function nevBeallitas($nev) + { + $this->nev = $nev; + } +} +]]> + </programlisting> + </informalexample> + </para> + + <para> + Nézzük, hogy van-e különbség az <varname>$obj1</varname> + és az <varname>$obj2</varname> objektum között. Az előbbi + a <literal>=</literal> másoló operátorral készült, az + utóbbi a <literal>=&</literal> referencia operátorral + készült. + + <informalexample> + <programlisting role="php"> +<![CDATA[ +$obj1 = new Ize('konstruktorban beállított'); +$obj1->nevKiiras(); +$globalref[0]->nevKiiras(); + +/* kimenete: +konstruktorban beállított +konstruktorban beállított +konstruktorban beállított */ + +$obj2 =& new Ize('konstruktorban beállított'); +$obj2->nevKiiras(); +$globalref[1]->nevKiiras(); + +/* kimenete: +konstruktorban beállított +konstruktorban beállított +konstruktorban beállított */ +]]> + </programlisting> + </informalexample> + </para> + <para> + Szemmel láthatóan nincs semmi különbség, de valójában + egy nagyon fontos különbség van a két forma között: + az <varname>$obj1</varname> és <varname>$globalref[0]</varname> + _NEM_ referenciák, NEM ugyanaz a két változó. Ez azért + történhet így, mert a "new" alapvetően nem referenciával + tér vissza, hanem egy másolatot ad. + <note> + <simpara> + Nincsenek teljesítménybeli problémák a másolatok visszaadásakor, + mivel a PHP 4 és újabb verziók referencia számlálást alkalmaznak. + Legtöbbször ellenben jobb másolatokkal dolgozni referenciák + helyett, mivel a referenciák képzése eltart egy kis ideig, de + a másolatok képzése gyakorlatilag nem igényel időt. Ha egyik + sem egy nagy tömb, vagy objektum, és a változásokat nem + szeretnéd mindegyik példányban egyszerre látni, akkor másolatok + használatával jobban jársz. + </simpara> + </note> + Hogy bebizonyítsuk, amit fent írtunk, lásd az alábbi kódot: + + <informalexample> + <programlisting role="php"> +<![CDATA[ +// Most megváltoztatjuk a nevet. Mit vársz? +// Számíthatsz arra, hogy mind $obj1 és $globalref[0] megváltozik... +$obj1->nevBeallitas('kívülről beállítva'); + +// mint korábban írtuk, nem ez a helyzet +$obj1->nevKiiras(); +$globalref[0]->nevKiiras(); + +/* kimenet: +konstruktorban beállított +kívülről beállítva */ + +// lássuk mi a különbség az $obj2 és $globalref[1] esetén +$obj2->nevBeallitas('kívülről beállítva'); + +// szerencsére ezek nem csak egyenlőek, hanem éppen ugyan az +// a két változó, így $obj2->nev és $globalref[1]->nev ugyanaz +$obj2->nevKiiras(); +$globalref[1]->nevKiiras(); + +/* kimenete: +kívülről beállítva +kívülről beállítva */ +]]> + </programlisting> + </informalexample> + </para> + <para> + Végül még egy utolsó példa, próbáld meg megérteni. + + <informalexample> + <programlisting role="php"> +<![CDATA[ +class A +{ + function A($i) + { + $this->ertek = $i; + // próbáld meg kitalálni, miért nem kell itt referencia + $this->b = new B($this); + } + + function refLetrehozas() + { + $this->c = new B($this); + } + + function ertekKiiras() + { + echo "<br>",get_class($this),' osztály: ',$this->value; + } +} + + +class B +{ + function B(&$a) + { + $this->a = &$a; + } + + function ertekKiiras() + { + echo "<br>",get_class($this),' osztály: ',$this->a->value; + } +} + +// próbáld meg megérteni, hogy egy egyszerű másolás +// miért okoz nem várt eredményeket a *-al jelölt sorban +$a =& new A(10); +$a->refLetrehozas(); + +$a->ertekKiiras(); +$a->b->ertekKiiras(); +$a->c->ertekKiiras(); + +$a->ertek = 11; + +$a->ertekKiiras(); +$a->b->ertekKiiras(); // * +$a->c->ertekKiiras(); + +/* +kimenete: +A osztály: 10 +B osztály: 10 +B osztály: 10 +A osztály: 11 +B osztály: 11 +B osztály: 11 +*/ +]]> + </programlisting> + </informalexample> + </para> + </sect1> + </chapter> <!-- Keep this comment at the end of the file