PHP kézikönyv
Előző | 18. Fejezet. Osztályok, objektumok (PHP 4-ben) | Következő

# Referenciák a konstruktorban

Referenciák képzése kontruktorokban problémás helyzetekhez vezethet. Ez a leírás segít a bajok elkerülésében.

`<?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; } } ?>`

Nézzük, hogy van-e különbség az $obj1 és az $obj2 objektum között. Az előbbi a = másoló operátorral készült, az utóbbi a =& referencia operátorral készült.

`<?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 */ ?>`

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 $obj1 és $globalref[0] _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.

> Megjegyzés: 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.

Hogy bebizonyítsuk, amit fent írtunk, lásd az alábbi kódot:

`<?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 */ ?>`

Végül még egy utolsó példa, próbáld meg megérteni.

`<?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(); ?>`

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

    A osztály: 10
    B osztály: 10
    B osztály: 10
    A osztály: 11
    B osztály: 11
    B osztály: 11

Előző | Tartalom | Következő
A speciális __sleep és __wakeup metódusok | Fel | Objektuok összehasonlítása