svn: /phpdoc/hu/trunk/language/ oop.xml
[email protected] (Ferenc Kovacs) Wed, 16 Nov 2011 19:55:34 +0000
| Newsgroups | php.doc.hu |
|---|---|
| Message-ID | <[email protected]> |
tyrael Wed, 16 Nov 2011 19:55:34 +0000
Revision: http://svn.php.net/viewvc?view=revision&revision=319363
Log:
removing the php4 oop doc as it is also removed from the english docs
Changed paths:
D phpdoc/hu/trunk/language/oop.xml
svn-diffs-319363.txt
(text/x-diff, 35.7 KB)
Deleted: phpdoc/hu/trunk/language/oop.xml
===================================================================
--- phpdoc/hu/trunk/language/oop.xml 2011-11-16 19:53:36 UTC (rev 319362)
+++ phpdoc/hu/trunk/language/oop.xml 2011-11-16 19:55:34 UTC (rev 319363)
@@ -1,1129 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- EN-Revision: n/a Maintainer: cece Status: ready -->
-<!-- CREDITS: gerzson, goba -->
-
- <chapter xml:id="language.oop" xmlns="http://docbook.org/ns/docbook">
- <title>Osztályok, objektumok (PHP 4-ben)</title>
- <sect1 xml:id="keyword.class">
- <title><literal>class</literal></title>
- <para>
- 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:
- </para>
- <para>
- <informalexample>
- <programlisting role="php">
-<![CDATA[
-<?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;
- }
- }
-}
-?>
-]]>
- </programlisting>
- </informalexample>
- </para>
-
- <para>
- 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.
- </para>
-
- <warning>
- <simpara>
- Egy osztálydefiníciót <emphasis>NEM</emphasis> szedhetsz szét több
- fájlra. Szintén <emphasis>NEM</emphasis> 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:
- </simpara>
- <para>
- <informalexample>
- <programlisting role="php">
-<![CDATA[
-<?php
-class teszt {
-<?php
-?>
- function teszt() {
- print 'oké';
- }
-}
-?>
-]]>
- </programlisting>
- </informalexample>
- </para>
- <simpara>
- Ez viszont rendben van:
- </simpara>
- <para>
- <informalexample>
- <programlisting role="php">
-<![CDATA[
-<?php
-class teszt {
- function teszt() {
- ?>
- <?php
- print 'oké';
- }
-}
-?>
-]]>
- </programlisting>
- </informalexample>
- </para>
- </warning>
-
- <simpara>
- Az alábbi figyelmeztetések a PHP 4-es verziójára érvényesek.
- </simpara>
-
- <caution>
-
- <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 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.
- </simpara>
- </caution>
-
- <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[
-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. . . */
- }
-}
-?>
-]]>
- </programlisting>
- </informalexample>
- <para>
- Az osztályok típusok, vagyis az aktuális változók tervrajzai.
- A kívánt típusú változót a <literal>new</literal> operátorral
- hozhatod létre.
- </para>
-
- <informalexample>
- <programlisting role="php">
-<![CDATA[
-<?php
-$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
- <varname>$kosar</varname> és <varname>$masik_kosar</varname> nevű
- objektumpéldányait. A <varname>$kosar</varname> 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
- <varname>$masik_kosar</varname> nevű kosárba.
- </para>
- <para>
- Mind a <varname>$kosar</varname>, mind a
- <varname>$masik_kosar</varname> 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ő
- <filename>OLVASSEL.TXT</filename> á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
- <literal>-></literal>.
- Ezért a <varname>$kosar->dolgok</varname> név és a
- <varname>$masik_kosar->dolgok</varname> név két különböző
- változót ad meg. Figyeld meg, hogy a változót
- <varname>$kosar->dolgok</varname> néven kell elérni, és nem
- <varname>$kosar->$dolgok</varname> néven, azaz a PHP változók
- neveibe csak egy dollárjelet kell tenned.
- </para>
- <informalexample>
- <programlisting role="php">
-<![CDATA[
-<?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
- <varname>$kosar</varname> vagy <varname>$masik_kosar</varname>
- néven nevezzük-e majd az objektumpéldányt. Ezért nem
- használhatod a Kosar osztályban a
- <varname>$kosar->dolgok</varname> 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
- <varname>$this</varname> kvázi-változót, amit 'a sajátom'
- vagy 'az aktuális objektumpéldány' értelemben alkalmazhatsz.
- Ezért a '<varname>$this->dolgok[$sorsz]</varname> +=
- <varname>$db</varname>' úgy olvasható, hogy 'adj
- <varname>$db</varname> darab <varname>$sorsz</varname> sorszámú
- terméket a saját dolgok tömbömhöz', vagy 'adj
- <varname>$db</varname> darab <varname>$sorsz</varname> sorszámú
- terméket az aktuális objektumpéldány dolgok tömbjéhez'.
- </para>
- <note>
- <para>
- A <varname>$this</varname> 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
- <varname>$this</varname> a meghívó objektumra fog hivatkozni.
- Ezt mutatja be szemléletesebben az alábbi példa:
- <informalexample>
- <programlisting role="php">
-<![CDATA[
-<?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();
-?>
-]]>
- </programlisting>
- &example.outputs;
- <screen>
-<![CDATA[
-$this definiálva van (a)
-$this nincs definiálva.
-$this definiálva van (b)
-$this nincs definiálva.
-]]>
- </screen>
- </informalexample>
- </para>
- </note>
- <note>
- <para>
- Van pár hasznos függvény az osztályok és objektumok kezeléséhez.
- Lásd az <link linkend="ref.classobj">Osztály és objektum
- függvények</link> című részt.
- </para>
- </note>
- </sect1>
-
- <sect1 xml:id="keyword.extends">
- <title><literal>extends</literal></title>
-
- <para>
- Gyakori, hogy szeretnél olyan osztályokat kialakítani, amelyek
- egy már meglévő osztályhoz hasonló tulajdonságokkal és
- metódusokkal rendelkeznek. 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 kiterjesztett, 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[
-<?php
-class Birtokolt_Kosar extends Kosar {
- var $tulaj;
- function tulajdonos_beallitasa($nev) {
- $this->tulaj = $nev;
- }
-}
-?>
-]]>
- </programlisting>
- </informalexample>
- <para>
- Ez definiál egy Birtokolt_Kosar nevű osztályt, ami a Kosar
- összes változójával és metódusával rendelkezik, és van egy
- saját változója, a <varname>$tulaj</varname>, no meg egy saját
- metódusa, a tulajdonos_beallitasa(). Az így gazdával ellátott
- kosarat a hagyományos módon hozhatod létre, és a kosár
- tulajdonosát is be tudod állítani, le tudod kérdezni [ebben
- az esetben favágó módszerrel]. A gazdás kosarakon továbbra is
- lehet használni a Kosar függvényeit:
- </para>
- <informalexample>
- <programlisting role="php">
-<![CDATA[
-<?php
-// Gazdás kosár létrehozása
-$gkosar = new Birtokolt_Kosar;
-// a tulaj beállítása
-$gkosar->tulajdonos_beallitasa("Namilesz Teosztasz");
-// a tulajdonos neve
-print $gkosar->tulaj;
-// (Kosar-ból öröklött funkcionalitás)
-$gkosar->berak("10", 1);
-?>
-]]>
- </programlisting>
- </informalexample>
- <para>
- Ezt "szülő-gyermek" kapcsolatnak is hívják. Egy osztály akkor válik
- szülőosztállyá, ha más osztály létrehozásakor ezt <emphasis>veszik
- alapul</emphasis> az <literal>extends</literal> kulcsszó használatával.
- Ezzel a kiterjesztéssel definiált osztályt hívjuk gyermek-osztálynak
- -- ebben a kapcsolatban. Ugyanis ezek után ez a gyermekosztály is lehet
- más osztályok szülőosztálya, ha belőle is származtatnak egy osztályt.
- </para>
- <note>
- <para>
- Az osztálydefinicióknak a további felhasználásuk előtt rendelkezésre kell
- állniuk! Ha a <literal>Gazdas_Kosar</literal>-ra van szükség a
- <literal>Kosar</literal> kiterjesztéseként, akkor előbb a
- <literal>Kosar</literal> osztályt kell definiálni. Ha egy újabb osztályt
- származtatunk <literal>Sarga_Gazdas_Kosar</literal> néven a
- <literal>Gazdas_Kosar</literal> osztályból, akkor a
- <literal>Gazdas_Kosar</literal> osztálydefiniciónak előbb kell szerepelnie.
- Röviden, az osztálydefiniciók sorrendje nagyon fontos. Az osztálydefiníciókat
- hierarchia legfelső szintjén álló osztállyal kell kezdeni, azzal, amelyik
- minden más osztálynak az ősének számít (szülő vagy nagy-, déd-, ük-,
- szépszülő).
- </para>
- </note>
- </sect1>
-
- <sect1 xml:id="language.oop.constructor">
- <title>Konstruktor</title>
- <para>
- A konstruktorok az osztályok olyan metódusai, amelyek
- automatikusan meghívásra kerülnek egy új objektumpéldány
- <literal>new</literal> kulcsszóval történő létrehozása során.
- Egy függvény akkor lesz konstruktor, ha a neve megegyezik
- az hordozó osztály nevével. Ha az osztálynak nincs konstruktora,
- a szülő osytály konstruktora lesz meghívva, már ha létezik.
- </para>
- <informalexample>
- <programlisting role="php">
-<![CDATA[
-<?php
-class Auto_Kosar extends Kosar {
- function Auto_Kosar () {
- $this->berak("10", 1);
- }
-}
-?>
-]]>
- </programlisting>
- </informalexample>
- <para>
- Ez egy olyan Auto_Kosar nevű osztályt [objektumtípust] hoz létre,
- mint a Kosar, csak rendelkezik egy konstruktorral, amely inicializálja
- a kosarat 1 darab "10"-es áruval, valahányszor a new operátorral
- hozzuk létre az objektumot. [de csak akkor!!!] A konstruktoroknak
- is lehet átadni paramétereket, és ezek lehetnek elhagyhatók is, amely még
- 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[
-<?php
-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;
-
-// Igazi vásárlás
-$masik_kosar = new Konstruktoros_kosar ("20", 17);
-?>
-]]>
- </programlisting>
- </informalexample>
- <para>
- Az <literal>@</literal> operátor használatával
- <emphasis>elnémíthatók</emphasis> a konstruktorban fellépő hibák,
- használata ilyen esetben: <literal>@new</literal>.
- </para>
- <informalexample>
- <programlisting role="php">
-<![CDATA[
-<?php
-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 {
-}
-
-// Ez meghívja B()-t, mint konstruktort
-$b = new B;
-]]>
- </programlisting>
- </informalexample>
- <para>
-
- Az A osztály B() metódusa hirtelen konstruktorrá
- válik a B osztályban, habár ez soha sem volt cél.
- A PHP 4 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>
- <caution>
- <simpara>
- 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>
- <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. Ennek pótálsaképp a legtöbb esetben
- jól alkalmazható a <function>register_shutdown_function</function>
- függvény.
- </para>
- </sect1>
- <sect1 xml:id="keyword.paamayim-nekudotayim">
- <title>Hatókör megadó operátor (<literal>::</literal>)</title>
- <caution>
- <simpara>
- Az alábbiak csak PHP 4-től érvényesek.
- </simpara>
- </caution>
- <para>
- Időnként hasznos az ősosztályok metódusaira vagy tulajdonságaira
- hivatkozni, vagy olyan osztálymetódusokat meghívni, amelyek
- nem példányosított objektumokhoz tartoznak. A :: operátor
- erre használható.
- </para>
- <informalexample>
- <programlisting role="php">
-<![CDATA[
-<?php
-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 az A osztály pelda() metódusát,
- habár nincs konkrét példányunk az A osztályból,
- tehát ezt nem írhatnánk le az <literal>$a->pelda()</literal>-hoz
- hasonlóan. Ehelyett a pelda() egy 'osztálymetódusként' viselkedik,
- azaz az osztály egy függvényeként, és nem egy példány metódusaként.
- </para>
- <para>
- Osztálymetódusok léteznek, de osztálytulajdonságok
- (változók) nem. Mivel a hívás pillanatában semmilyen
- objektum nem létezik, egy osztálymetódus nem használhat
- objektum változókat, és egyáltalán nem használhatja a
- <varname>$this</varname> speciális referenciát. Egy
- objektummetódus azonban természetesen dolgozhat globális
- változókkal és lokális változókkal is.
- </para>
- <para>
- A fenti példa a B osztályban felüldefiniálja a pelda()
- metódust. Az A osztálytól örökölt eredeti definíció eltűnik,
- és többé nem érhető el, hacsak nem az A osztályban
- megvalósított pelda() függvényre hivatkozol közvetlenül,
- a :: operátor segítségével. Ennek eléréséhez A::pelda()-t
- kell használni (ebben az esetben írhatnál parent::pelda()-t is,
- ahogy az a következő szakaszban olvasható).
- </para>
- <para>
- Ebben a környezetben van aktuálisan használt objektum,
- és ennek lehetnek objektum változói (tulajdonságai).
- Ekképpen ha egy objektummetóduson belül használod ezt
- az operátort, akkor alkalmazhatod a
- <varname>$this</varname>-t, és felhasználhatod az
- objektum tulajdonságait.
- </para>
- </sect1>
- <sect1 xml: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[
-<?php
-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 xml: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>
- visszaalakít 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 lehessen állítani egy objektumot, az objektum
- osztályának (típusának) már definiálva kell lennie. Ez a
- következőket jelenti egy példán keresztül megvilágítva:
- Ha az elso.php oldalon az A osztályú <varname>$a</varname>
- objektumot szerializálod, akkor kapsz egy olyan
- karaktersorozatot, amely az A osztályra hivatkozik, és
- tartalmazza az összes <varname>$a</varname>-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ú <varname>$a</varname> nevű
- objektumot, akkor az A osztály definíciójának rendelkezésre
- kell állnia 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[
-<?php
-// 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");
- fwrite($fp, $s);
- fclose($fp);
-
-// masodik.php:
- // ez szükséges, hogy a deszerializáció rendben menjen
- 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> meghívásával,
- akkor be kell töltened az <literal>aosztaly.inc</literal>
- külső állományt minden oldalon, nem csak az elso.php
- és masodik.php programokban.
- </para>
- </sect1>
- <sect1 xml: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, amely tartalmazza az adott
- objektum ténylegesen szerializálandó tulajdonságainak neveit.
- </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. Hasznos
- lehet akkor is, ha nagyon nagy objektumaid vannak, amelyeket
- 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 xml: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[
-<?php
-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[
-<?php
-$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[
-<?php
-// 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[
-<?php
-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();
-?>
-]]>
- </programlisting>
- &example.outputs;
- <screen>
-<![CDATA[
-A osztály: 10
-B osztály: 10
-B osztály: 10
-A osztály: 11
-B osztály: 11
-B osztály: 11
-]]>
- </screen>
- </informalexample>
- </para>
- </sect1>
- <sect1 xml:id="language.oop.object-comparison">
- <title>Objektuok összehasonlítása</title>
- <para>
- PHP 4-ben az objektumok igen egyszerű módon kerülnek összevetésre:
- Két objektumpéldány megegyezik, ha azonos attribútumaik, értékeik
- vannak, és ugyanazon osztály megtestesülései. Hasonló szabályok
- érvényesek két objektum azonosságának vizsgáltaára az egyezőség operátor
- (<literal>===</literal>) hasznélatakor.
- </para>
- <para>
- Ha a lenti példakódot lefuttatjuk:
- <example>
- <title>Példa objektum-összehasonlításra PHP 4-ben</title>
- <programlisting role="php">
-<![CDATA[
-<?php
-function bool2str($bool) {
- if ($bool === false) {
- return 'HAMIS';
- } else {
- return 'IGAZ';
- }
-}
-
-function compareObjects(&$o1, &$o2) {
- echo 'o1 == o2 : '.bool2str($o1 == $o2)."\n";
- echo 'o1 != o2 : '.bool2str($o1 != $o2)."\n";
- echo 'o1 === o2 : '.bool2str($o1 === $o2)."\n";
- echo 'o1 !== o2 : '.bool2str($o1 !== $o2)."\n";
-}
-
-class Flag {
- var $flag;
-
- function Flag($flag=true) {
- $this->flag = $flag;
- }
-}
-
-class SwitchableFlag extends Flag {
-
- function turnOn() {
- $this->flag = true;
- }
-
- function turnOff() {
- $this->flag = false;
- }
-}
-
-$o = new Flag();
-$p = new Flag(false);
-$q = new Flag();
-
-$r = new SwitchableFlag();
-
-echo "Azonos paraméterekkel létrehozott példányok összehasonlítása\n";
-compareObjects($o, $q);
-
-echo "\nEltérő paraméterekkel létrehozott példányok összehasonlítása\n";
-compareObjects($o, $p);
-
-echo "\nEgy szülő és annak gyerek osztályábók képzett példényok összehasonlítása\n";
-compareObjects($o, $r);
-?>
-]]>
- </programlisting>
- &example.outputs;
- <screen>
-<![CDATA[
-Azonos paraméterekkel létrehozott példányok összehasonlítása
-o1 == o2 : IGAZ
-o1 != o2 : HAMIS
-o1 === o2 : IGAZ
-o1 !== o2 : HAMIS
-
-Eltérő paraméterekkel létrehozott példányok összehasonlítása
-o1 == o2 : HAMIS
-o1 != o2 : IGAZ
-o1 === o2 : HAMIS
-o1 !== o2 : IGAZ
-
-Egy szülő és annak gyerek osztályábók képzett példényok összehasonlítása
-o1 == o2 : HAMIS
-o1 != o2 : IGAZ
-o1 === o2 : HAMIS
-o1 !== o2 : IGAZ
-]]>
- </screen>
- </example>
- Ez tehát az az elvárt működés, amit a fentebb megfogalmazott szabályok
- alapján tapasztalnunk kell. Csak azon példányok fognak megegyezőnek
- bizonyulni, amelyeknek azonos értékeik és attribútumaik vannak és
- egyazon osztályból lettek példányosízva.
- </para>
- <para>
- Akkor is ezek a szabályok vannak érvényben, ha több, egységbe foglalt
- objektum egyben való vizsgálatáról van szó. A következő példában
- egy olyan hordozó osztályt hasznélunk, amely egy asszociatív tömbben
- tárol a fenti példából már ismert <classname>Flag</classname> típusú
- objektumokat.
- <example>
- <title>Vegyített objektumok összehasonlítása PHP 4-ben</title>
- <programlisting role="php">
-<![CDATA[
-<?php
-class FlagSet {
- var $set;
-
- function FlagSet($flagArr = array()) {
- $this->set = $flagArr;
- }
-
- function addFlag($name, $flag) {
- $this->set[$name] = $flag;
- }
-
- function removeFlag($name) {
- if (array_key_exists($name, $this->set)) {
- unset($this->set[$name]);
- }
- }
-}
-
-$u = new FlagSet();
-$u->addFlag('flag1', $o);
-$u->addFlag('flag2', $p);
-$v = new FlagSet(array('flag1'=>$q, 'flag2'=>$p));
-$w = new FlagSet(array('flag1'=>$q));
-
-echo "\nVegyes objektumok: u(o,p) és v(q,p)\n";
-compareObjects($u, $v);
-
-echo "\nu(o,p) and w(q)\n";
-compareObjects($u, $w);
-?>
-]]>
- </programlisting>
- &example.outputs;
- <screen>
-<![CDATA[
-Vegyes objektumok: u(o,p) és v(q,p)
-o1 == o2 : IGAZ
-o1 != o2 : HAMIS
-o1 === o2 : IGAZ
-o1 !== o2 : HAMIS
-
-u(o,p) and w(q)
-o1 == o2 : HAMIS
-o1 != o2 : IGAZ
-o1 === o2 : HAMIS
-o1 !== o2 : IGAZ
-]]>
- </screen>
- </example>
- </para>
- </sect1>
-
-
- </chapter>
-
- <!-- Keep this comment at the end of the file
- Local variables:
- mode: sgml
- sgml-omittag:t
- sgml-shorttag:t
- sgml-minimize-attributes:nil
- sgml-always-quote-attributes:t
- sgml-indent-step:1
- sgml-indent-data:t
-indent-tabs-mode:nil
- sgml-parent-document:nil
- sgml-default-dtd-file:"~/.phpdoc/manual.ced"
- sgml-exposed-tags:nil
- sgml-local-catalogs:nil
- sgml-local-ecat-files:nil
- End:
- vim600: syn=xml fen fdm=syntax fdl=2 si
- vim: et tw=78 syn=sgml
- vi: ts=1 sw=1
- -->