ugrás a tartalomhoz

PHP5 RC3 __set() és __get() tagfüggvények

LeslieNice · 2004. Jún. 25. (P), 21.49
Egy érdekes dologgal találkoztam a php5 rc3-ban a __set() és __get() tagfüggvényekkel kapcsolatban. Egy példakódot copy-paste -eltem az alábbi címről
http://zend.com/manual/migration5.oop.php
és a kód itt van külön
http://www.universale.hu/test.php.txt -ben.
Amikor kiegészítettem a példakódot az alábbi sorral, hogy print $foo->x["a"]++; Akkor a __set() és __get() függvények nem hívódtak meg, ellenben a $foo->a++; esetben amikor meghívódtak és a $foo->x["a"]-ra. Az nem világos, hogy miért nem hívódnak meg ilyenkor (esetleg bug)?

Köszönettel előre is minden választ
Szép László
 
1

Re: PHP5 RC3 __set() és __get() tagfüggvények

T.G · 2004. Jún. 25. (P), 22.59
Nekem valamiért ez az egész logikátlan.
Ha a példaprogit lefutattom, akkor a $foo->n = 1; utasításnál sem futott le a __set() függvény, ebből arra gondolok, hogy csak akkor fut le, ha olyan attributumra hivatkozunk, ami nem létezik, és mikor te a $foo->x -re hivatkozol, akkor az létezik.
De ez inkább csak vaktába tapogatozás...

Mindenesetre nem láttom azt a problémát, amit ezzekkel kellene megoldani. :)
2

Csak kiváncsiság

LeslieNice · 2004. Jún. 25. (P), 23.40
Én sem látom a problémát amit ezzel kéne megoldani, engem is csak a kiváncsiság vezérelt :)

Szerintem is akkor fut le a set amikor nem létezik az attribútum, de akkor meg a gondom az, hogy $foo->s++; utasításnál a $foo->s nem létezik lefut és azt mondja 'Setting [s] to 1 Not OK!'. Viszont $foo->a=100; -nál $foo->a ugyanúgy nem létezik lefut de ekkor pedig nem ezt mondja hogy 'Setting [s] to 100 Not OK!', hanem hogy 'Setting [a] to 100 OK!' és $foo->x["a"] -t 100-ra állítja, pedig erről az attribútumról szó sincs:). Sőt utána amikor még mindig nem létezik a $foo->a attribútum (a var_dump() szerint sem), a $foo->a++ utasításnál lefut a set és a get és azt mondja hogy 'Getting [a] Returning: 100 Setting [a] to 101 OK!' (itt s $foo->x["a"]-t változtatja ismét!). Akkor a set-nél ez azt jelenti, hogy a $foo->a nem létezik hiszen lefut, de ha nem létezik akkor a get hogyan ad 100-t vissza a set előtt?

Ha $foo->a pedig ekvivalens $foo->x["a"]-val az pedig furcsa lenne... ( de lehet hogy csak nem olvastam még ezzel kapcsolatban semmit )Szóval már nekem is logikátlan az egész :D
3

Re: Csak kiváncsiság

T.G · 2004. Jún. 26. (Szo), 00.08
Na várjál, azért ennyire nem logikátlan. :)

a set/get megnézi, hogy a $this->x[valami] létezik-e, és ez alapján írja ki, hogy sikerült a x[valami] írása/olvasása.

$foo->s = 1; ennél az utasításnál a $foo->s nem létezése miatt fut le a set, majd mivel a $x tömbnek nincs "s" indexe ezért írja ki a Not OK! -t.
Ellenben a $foo->a = 1; utasításnál a $foo->a nem létezése miatt fut le a set, majd mivel a $x tömbnek van "a" indexe ezért írja ki a OK! -t. Majd a $x['a']-t írja át 1-re.
Végül $foo->n = 1; esetben létezik n attribum, így a set nem is fut le. (és szerintem ez itt bug, vagy egy olyan feature, aminek nem láttom az értelmét)
4

__get(), __set() értelme...

Heilig Szabolcs · 2004. Jún. 26. (Szo), 00.31
A két tagfüggvény segítségével virtuális változókat tudsz létrehozni. Olyan értékeket tudsz lekérni az objektumból ami nem létezik közvetlenül, de különféle más értékekbõl származtatható. Pl van egy $gaz nevu objektumod, aminek van egy $gaz->terfogat es egy $gaz->tomeg belso valtozoja, amiket valtoztathatgatsz. Viszont a $gaz->suruseg lekeresere irhatsz egy algoritmust, ami ropteben kiszamolja neked ezt, es visszaadja. Viszont esetleg ugyanezen virtualis valtozo ertekenek irasat meg tudod tagadni, mivel az kozvetlenul nem valtoztathato, szarmaztatott ertek. Igenis megvan a maga haszna! :)
5

Így már világosabb

LeslieNice · 2004. Jún. 26. (Szo), 00.55
Köszi, így már világos a dolog, már csak azt nem értem(jük) hogy a $foo->a esetén miért a $foo->x["a"] létező attribútumot változtatgatja, miért nem a $foo->a virtuális attribútumot kezeli?
6

Ilyen ötlete volt :)

Heilig Szabolcs · 2004. Jún. 26. (Szo), 01.05
Nem tudom, miért ezt a példát választotta az illetõ. Elvileg ilyet is lehet vele, de elég idétlen példa. :)
7

Re: __get(), __set() értelme...

T.G · 2004. Jún. 26. (Szo), 10.25
Lehet, hogy csak én látom így, de ez egy tipikus gányoljuk, de nagyot módszer. Mennyivel átláthatóbb a kód akkor, ha lesz egy getSuruseg() [vagy suruseg()], mintha a __get() -ben egy switch ágban van benne a suruseg. Főleg, ha az ember használ valami eszközt, ami többet tud, mint a notepad, akkor hasznos, ha kijelzi milyen attribumaink, és milyen alprogramjaink vannak.
Az persze világos, hogy van értelme, nem is akartam írni a bugreportra, de biztos vagyok benne, hogy én ilyet nem használnék.
(talán a __get() -be egy warrning, __set() -be error :)
8

egy feladat - sok megoldás

T.G · 2004. Jún. 26. (Szo), 11.19
Annyit mindenképpen meg kell említeni az előző hozzászólásom ellen, hogy a PHP eddig is remekül követte azt az elvet, hogy egy feladathoz sokféle megoldást lehessen készíteni. Azaz, ha valakinek az egyik szerkezet nem tetszik, akkor nem szükséges azt használnia, mert biztos, hogy másként is megvalósítható. :)
9

SimpleXML

Hojtsy Gábor · 2004. Jún. 26. (Szo), 15.32
A simpleXML peldául előre nem definiálható tulajdonságokat tesz elérhetővé, az XML állomány tagjei alapján generálja. Namost ha nem lenne ez a __get()/__set() megoldás, akkor nem tudnál egyszerűen hivatkozni a tagekre, hanem metódusokat kellene hívni (amihez a __call() kell). Ha meg __call() sem lenne, akkor egy generikus függvényt kellene hívnod, aminek nem sok értelme van, mert már az objektummal magával jelzed, hogy mit akarsz (egyszerűen kezelni az XML-t). Tehát szerintem (és sokan mások szerint) ez növeli a programod átláthatóságát, mert a fölösleges OO szintaxistól megszabadulsz.
10

Megvilágosodás

LeslieNice · 2004. Jún. 26. (Szo), 16.57
Mostmár megvilágosodtam a témával kapcsolatban, és a SimpleXML-es példa tényleg 100%-osan megmutatja a lényegét a dolognak. Köszi! Egyébként az új PHP5 feature-knek hol lehet ilyen mélységeiben utánaolvasni vagy ha nem is ilyen mélységeiben de mélyebben mint a zend honlapon van? A zendet már átbogarásztam (meg sok más helyet is) és elég sok info van fent, de sok minden csak utalás szintjén, vagy lehet hogy csak én voltam béna :(. A legjobb amit találtam a http://www.zend.com/engine2/ZendEngine-2.0.pdf volt, de ez azért messze nem teljes.
11

Szia! [i]Lehet, hogy csak

Hodicska Gergely · 2004. Jún. 29. (K), 01.03
Szia!

Lehet, hogy csak én látom így, de ez egy tipikus gányoljuk, de nagyot módszer. Mennyivel átláthatóbb a kód akkor, ha lesz egy getSuruseg() [vagy suruseg()], mintha a __get() -ben egy switch ágban van benne a suruseg.


Ez is egy olyan lehetoseg, amit lehet jol es rosszul hasznalni. Konnyen elkepzelhetoek olyan szituaciok, amikor hasznos tud lenni. Ott van a Goba altal emlitett eset, de peldaul egy RecordSet eseten is milyen jol jon majd. Nem kell ezt irogatno: $rs->fields['x'], helyette $rs->x.
Igazabol a gond az oroklodes kapcsan jon majd elo az ezen lehetoseget hasznalo osztalyok eseten. Ha egy osztaly hasznalja a __set/get lehetosegeket, es az ot kiterjeszto osztaly is szeretne ilyen "tagvaltozokat" hasznalni, akkor ugy kell a sajat __set/get mwetodusait megirni, hogy a szulo __set/get metodusai feladatat is ellatsa. Tehat a leszarmazott osztaly "jobban" kell ismerje a szulo osztaly mukodeset, mint normal esetben.

Felho