Referencje wewnątrz konstruktora

Tworzenie referencji wewnątrz konstruktora może prowadzić do dziwnych efektów . Ten rozdział ma pomóc w unikaniu takich problemów .

 
class

 
Foo

 
{

 
function

 
Foo($nazwa

 
)

 
    {

 
/

 
/

 
stworz

 
referencje

 
wewnatrz

 
globalnej

 
tablicy

 
$globalref

 
global

 
$globalref

 
;

 
$globalref[

 
]

 
=

 
$this

 
;

 
/

 
/

 
ustaw

 
nazwę

 
na

 
przekazaną

 
wartość

 
$this

 
-

 
ustawNazwe($nazwa)

 
;

 
/

 
/

 
i

 
wyświetl

 


 
$this

 
-

 
wyswietlNazwe()

 
;

 
    }

 
function

 
wyswietlNazwe(

 
)

 
    {

 
echo

 
"

 
br

 
",$this

 
-

 
nazwa

 
;

 
    }

 
function

 
ustawNazwe($nazwa

 
)

 
    {

 
$this

 
-

 
nazwa

 
=

 
$nazwa

 
;

 
    }

 
}





Sprawdźmy , czy jest jakaś różnica pomiędzy $bar1 , który jest tworzony przy pomocy operatora przypisania = , a $bar2 , który został stworzony używając operatora referencji = .. .

 
$bar1

 
=

 
new

 
Foo(

 
'ustawione

 
w

 
konstruktorze')

 
;

 
$bar1

 
-

 
wyswietlNazwe()

 
;

 
$globalref[0]

 
-

 
wyswietlNazwe()

 
;

 
/

 
*

 
wyjście

 
:

 
ustawione

 
w

 
konstruktorze

 
ustawione

 
w

 
konstruktorze

 
ustawione

 
w

 
konstruktorze

 
*

 
/

 
$bar2

 
=

 
new

 
Foo('ustawione

 
w

 
konstruktorze')

 
;

 
$bar2

 
-

 
wyswietlNazwe()

 
;

 
$globalref[1]

 
-

 
wyswietlNazwe()

 
;

 
/

 
*

 
wyjście

 
:

 
ustawione

 
w

 
konstruktorze

 
ustawione

 
w

 
konstruktorze

 
ustawione

 
w

 
konstruktorze

 
*

 
/





Wydaje się , że nie ma żadnej różnicy , ale na prawdę jest jedna , i to bardzo istotna : $bar1 i $globalref[ 0 ] NIE referencjami , NIE samą zmienna . Dzieje się tak , ponieważ " new " nie zwraca domyślnie referencji , ale kopię .

Notatka : Zwracanie kopii zamiast referencji nie powoduje utraty wydajności ( od PHP 4 używane jest zliczanie referencji ) . Jednakże zazwyczaj lepiej jest pracować poprostu z kopiami zamiast referencji , poniewać tworzenie referencji zabiera trochę czasu , podczas gdy tworzenie kopii obiektów teoretycznie w ogóle nie zabiera czasu ( chyba że któraś z tych zmiennych jest dużą tablicą lub obiektem i jedno z nich ulega zmianie , po czym tej samej zmianie ulegają pozostałe zmienne ; wtedy lepiej jest użyć referencji do zmieniania ich równolegle ) .

Aby udowodnić to, co zostało zapisane powyżej, przyjrzyjmy się poniższemu programowi.
 
/

 
/

 
teraz

 
zmienimy

 
nazwę

 
.

 
czego

 
się

 
spodziewasz

 
?

 
/

 
/

 
możesz

 
się

 
spodziewać

 
,

 
że

 
i

 
$bar1

 
i

 
$globalref[

 
0

 
]

 
zmienią

 
swoje

 
nazwy..

 
.

 
$bar1

 
-

 
ustawNazwe('ustawiona

 
z

 
zewnątrz')

 
;

 
/

 
/

 
jak

 
napisano

 
powyżej

 
,

 
nic

 
takiego

 
się

 
nie

 
stanie

 
$bar1

 
-

 
wyswietlNazwe()

 
;

 
$globalref[0]

 
-

 
wyswietlNazwe()

 
;

 
/

 
*

 
wyjście

 
:

 
ustawiona

 
z

 
zewnątrz

 
ustawiona

 
w

 
konstruktorze

 
*

 
/

 
/

 
/

 
zobaczmy

 
co

 
się

 
dzieje

 
z

 
$bar2

 
i

 
$globalref[1

 
]

 
$bar2

 
-

 
ustawNazwe('ustawiona

 
z

 
zewnątrz')

 
;

 
/

 
/

 
na

 
szczęście

 
ta

 
zmienna

 
nie

 
zachowuje

 
się

 
jak

 
ta

 
z

 
poprzedniego

 
przypadku

 
/

 
/

 


 
to

 
te

 
same

 
zmienne

 
,

 
z

 
więc

 
$bar2

 
-

 
nazwa

 
i

 
$globalref[1]

 
-

 
nazwa

 


 
także

 
/

 
/

 
tymi

 
samymi

 
zmiennymi

 
$bar2

 
-

 
wyswietlNazwe()

 
;

 
$globalref[1]

 
-

 
wyswietlNazwe()

 
;

 
/

 
*

 
wyjście

 
:

 
ustawiona

 
z

 
zewnątrz

 
ustawiona

 
z

 
zewnątrz

 
*

 
/





Ustatni przykład . Postaraj się go zrozumieć /

 
class

 
A

 
{

 
function

 
A($i

 
)

 
    {

 
$this

 
-

 
wartosc

 
=

 
$i

 
;

 
/

 
/

 
domyśl

 
się

 
dlaczego

 
nie

 
potrzebujemy

 
tutaj

 
referencji

 
$this

 
-

 
b

 
=

 
new

 
B($this)

 
;

 
    }

 
function

 
stworzRef(

 
)

 
    {

 
$this

 
-

 
c

 
=

 
new

 
B($this)

 
;

 
    }

 
function

 
wyswietlWartosc(

 
)

 
    {

 
echo

 
"

 
br

 
"

 
,"klasa

 
",get_class($this)

 
,'

 
:

 
',$this

 
-

 
value

 
;

 
    }

 
}

 
class

 
B

 
{

 
function

 
B

 
(

 
$a

 
)

 
    {

 
$this

 
-

 
a

 
=

 
$a

 
;

 
    }

 
function

 
wyswietlWartosc(

 
)

 
    {

 
echo

 
"

 
br

 
"

 
,"klasa

 
",get_class($this)

 
,'

 
:

 
',$this

 
-

 
a

 
-

 
value

 
;

 
    }

 
}

 
/

 
/

 
spróbuj

 
zrozumieć

 
dlaczego

 
użycie

 
tu

 
prostego

 
kopiowania

 
może

 
powodować

 
/

 
/

 
nieporządany

 
efekt

 
w

 
linii

 
uznaczonej

 
znaczkiem

 
'*

 
'

 
$a

 
=

 
new

 
A(10)

 
;

 
$a

 
-

 
stworzRef()

 
;

 
$a

 
-

 
wyswietlWartosc()

 
;

 
$a

 
-

 
b

 
-

 
wyswietlWartosc()

 
;

 
$a

 
-

 
c

 
-

 
wyswietlWartosc()

 
;

 
$a

 
-

 
value

 
=

 
11

 
;

 
$a

 
-

 
wyswietlWartosc()

 
;

 
$a

 
-

 
b

 
-

 
wyswietlWartosc()

 
;

 
/

 
/

 
*

 
$a

 
-

 
c

 
-

 
wyswietlWartosc()

 
;

 
/

 
*

 
wyjście

 
:

 
klasa

 
A

 
:




 
10

 
klasa

 
B

 
:




 
10

 
klasa

 
B

 
:




 
10

 
klasa

 
A

 
:




 
11

 
klasa

 
B

 
:




 
11

 
klasa

 
B

 
: