PHP5: Referenties naar niet bestaande objecten
March 10th, 2007 by DavyEen tijdje geleden zat ik vrij OO bezig en stuitte ik op iets wat ik eigenlijk had moeten voorzien. Eén hoofdclass hield een template object bij en een drietal andere classes hadden een referentie naar dit object. Onder zekere voorwaarden werd het eigenlijke object opnieuw aangemaakt. Hierdoor gingen alle referenties in die drie andere classes op zichzelf bestaan en was de “verwijzing” niet langer..
Het relaas van dit alles is vrij simpel. Als je éénzelfde object van verschillende locaties aanspreekt, kijk dan goed uit als je dit object om de één of andere reden opnieuw zou moeten aanmaken, want de verwijzingen zijn “dood”.


March 11th, 2007 at 07:22
Hmm, ge gaat uw OO boek toch nog eens moeten lezen
Wat je doet met “unset()” is een variabele unsetten. (Soms zijn functienamen goed gekozen he?) Wat je niet doet, is dat object volledig deleten. Je verwijdert enkel de link tussen wat jij “$whip” noemt, en een bepaalde instantie van de klasse Whiplash. Jammer dat je in PHP geen ‘free()’ functie hebt die wel een object compleet kan deleten. De garbage-collector (de mannen van den ivago) komen pas om je object als er geen enkele referentie meer naar bestaat.
Wat je ziet, is dus perfect documented en expected behaviour!
March 11th, 2007 at 09:41
En je geeft ook niet echt per referentie mee. PHP gaat zich misschien wel zo gedragen voor sommige objecten maar als je expliciet iets byref wil meegeven moet je werken met &$object. Zie http://php.mirror.camelnetwork.com/manual/en/language.references.php
March 11th, 2007 at 10:52
@Jan: je bent fout, vanaf php5 geeft php standaard objectjen by reference mee
En Frank heeft natuurlijk volledig gelijk, het gedrag is perfect normaal.
March 11th, 2007 at 17:32
@Slicer: correct, maar daar zeg je het meteen, objecten. Aangezien je niet altijd weet wat je gaat meegeven is het aan te raden je by-references er expliciet in te steken, want bij strings en int geeft hij ze nog steeds niet by-ref mee.
March 11th, 2007 at 23:15
@Frank, als ik nu 3 classes had dan zouden dit 3 aparte op zich zelf bestaande objecten worden, door het unsetten van de $whip variabele. Daar zijn we het over eens right?
March 12th, 2007 at 08:00
Davy, euh, nee? Aangezien het objecten zijn, worden die byref ipv byval doorgegeven (objecten byval doorgeven is trouwens vies en memory/cpu duur). Het is hetzelfde object.
Maw: stel dat je hebt (pseudocode, heb nog geen 2 koffies op, dus er komt nog geen echte code uit):
$Ei = new Whiplash(“Paasei”);
$BelgischMandje = new Foo($Ei);
$LuxemburgsMandje = new Foo($Ei);
$ZwitsersMandje = new Foo($Ei);
unset($Ei);
Je 3 mandjes bevatten nog altijd dezelfde instantie van het object Whiplash. Stel dat je een functie in uw klasse Foo hebt die iets aanpast aan uw deelobject, dan ga je zien dat het bij de andere ook aangepast is. Als dat niet zo zou zijn, mag PHP zich nooit meer een OO taal noemen
Frank
(ps: $FiscusControleur kan aan je drie mandjes! Ha!)
March 12th, 2007 at 08:28
Deze middag ff een brok code in mekaar plakken zoals het was, dan zie je waar mijn wrevel zich bevindt
March 12th, 2007 at 09:51
Het gedraagt zich toch zoals het hoort. De unset functie doet misschien niet wat je verwacht dat ze doet, maar php heeft (zoals Frank) al aanhaalt geen mogelijkheid om een object expliciet en geforceerd te destroyen.
Een object heeft een lifetime. Deze is helemaal niet gekoppeld aan een variabele die toevallig de referentie heeft. Er bestaat geen manier om dat via een voorbeeldje weer te geven, maar in jullie voorbeeld is $whip slechts een eenvoudige verwijzing naar dat object. Er kunnen 1, 10, 20 of 100 verwijzingen zijn. Zolang er verwijzingen zijn, bestaat het object (en kan je eraan). Verwijzingen weg == object is “lost in space”, en normaal gaat de garbage collector dan langskomen om dat op te ruimen. Als ik eens wat meer tijd heb, ga ik dat eens proberen aan te tonen. Ik ben zelfs niet zeker dat de garbage collector onmiddellijk langskomt.
Misschien nog meer schokkend: de destructor van php gaat zelfs het object niet verwijderen, die voert gewoon de functie uit, maar het object blijft bestaan. Wanneer je dus een referentie hebt naar een ge-destruct object, dan kan je dit verder blijven gebruik. Zeer vies. Maar we wisten al dat php het OO-luik ietwat smerig opgelost had. Bij php5 is het al een stuk beter, maar nog altijd heeft het scherpe kantjes. (Reden te meer om naar ruby over te schakelen, wat een echte OO-taal is
).
April 24th, 2008 at 09:05
Hallo
way to late om een reactie te geven natuurlijk maar ik kwam op deze pagina via een grote zoekmachine. Objects worden in PHP5 niet by ref meegegeven. Ze doen alsof ze by reference worden meegegeven maar intern worden ze anders verwerkt. For an example: http://blog.libssh2.org/index.php?/archives/51-Youre-being-lied-to..html
March 15th, 2010 at 16:14
Ëó÷øèå ïëÿæè Þæíî-Êèòàéñêîãî ìîðÿ…
Âüåòíàì – ñòðàíà ñ äðåâíåéøåé èñòîðèåé è êóëüòóðîé…