Jump to content

Removing an object's properties


ShadowMage

Recommended Posts

Hi guys,I'm trying to remove a property from an object, but for some reason when I try to access the property, it still recognizes that it is/was a property. Here's the whole scoop:I have a class, SkylightSet. This class has a property called Skylights, which is an array of Skylight objects, created from a Skylight class. Each Skylight object has a property called ParentSet, which holds a reference to the parent SkylightSet object. I am trying to get rid of the recursion that occurs by using this reference. The recursion occurs because the ParentSet is a reference to the SkylightSet object, which has the Skylight object stored in the Skylights property, which has a reference to the SkylightSet object, which has the Skylight object stored in the Skylights property, which has a....well, you get the idea....:)Anyway, I thought this might be bad for resources so I'm trying to remove this recursion. (But maybe I'm wrong and it doesn't really matter much as far as resources are concerned and I'm just wasting my time. If so somebody please tell me.)Here's my test code:

class SkylightSet {	public $GlazeType;	private $Skylights;	public function __construct() {		$this->GlazeType = 'G275';		$this->Skylights = array();	}	public function addSkylight($skylight) {		//Remove the Skylights array to prevent recursion		$myParent = clone $this;		unset($myParent->Skylights);		$skylight->ParentSet = $myParent;		array_push($this->Skylights, $skylight);	}}abstract class Skylight {	public $Width;	public $Length;	public $ParentSet;	public function __construct($w, $l) {		$this->Width = $w;		$this->Length = $l;	}}class WallPanel extends Skylight {	public $Description;	public function __construct($w, $l) {		parent::__construct($w, $l);		$this->Description = 'Wall Panel System';	}	public function getGlazeType() {		return $this->ParentSet->GlazeType;	}	public function dumpParent() {		echo "<pre>".print_r($this->ParentSet, true)."</pre>";	}}$testSet = new SkylightSet();echo "Before adding skylight:<br /><pre>".print_r($testSet, true)."</pre>";$newSkylight = new WallPanel(12, 34);$testSet->addSkylight($newSkylight);echo "After adding skylight:<br /><pre>".print_r($testSet, true)."</pre>";echo "<br /><br />\n";echo "<pre>".print_r($newSkylight->getGlazeType(), true)."</pre>";echo "<pre>".print_r($newSkylight->dumpParent(), true)."</pre>";echo "<pre>".print_r($newSkylight->ParentSet->Skylights, true)."</pre>";

The dump of the ParentSet property doesn't show the Skylights collection, but the last line prints a fatal error stating "cannot access private property". Obviously, I expected an error on that line, but the error I expected was "undefined property". :)Interestingly, if I change the Skylights property from private to public, I do actually get an "undefined property" error. So either way, the property cannot be accessed but I'm just curious why it isn't undefined when it's a private property.......Or perhaps someone knows a better way to do what I'm trying to do. I need to have an object (SkylightSet) which stores a collection of other objects (Skylights). Each object (Skylight) in the collection needs to have access to properties of the "parent" object (SkylightSet) without actually having those properties itself or having them passed in through a constructor or setter method.If you do have any ideas, please share them.Thanks.

Link to comment
Share on other sites

It shouldn't be a problem to have each object have a link to it's parent. The funny thing is that when you create an object and it's given a space in the ram you don't actually duplicate the information like you would with another variable. As in-

$x = 10;$y = $x;$y += 10;

So now x is 10 and y is 20. But objects don't give their values like this just a link to the object in the memory.

$Object1 = new Object();$Object2 = $Object1;$Object2->someProperty = 10;

Now someProperty is 10 in both objects because you just set Object2 as the same reference number as Object1 (something like #FB01F7 which is a location in the memory). So this won't cause any kind of recursion.HOWEVERThis is how other programming languages do it and I learned this while taking a Java class. I'm pretty certain php works the same way. And as long as I'm not reading it incorrectly, I believe the page on the php website says the same thing.http://www.php.net/manual/en/language.oop5.references.phpAs for the private variable. If you are trying to get a private variable then it will stop dead when it sees the variable is private and it's not of the same class, regardless of the value. You may be thinking that an extended class should be able to use private variables but private is strictly for that class only and not even extended classes. You can use protected which works the same way as private but does extend the privilege to sub classes.

Link to comment
Share on other sites

In Object-oriented programming you cannot add or remove properties from an object, you can just set their values.There is no problem having an object referencing its parent. That's normal and doesn't waste any resources. You just need to be sure to remove the links when you remove an object.You shouldn't be cloning the objects, just referencing them.Do this instead:

public function addSkylight($skylight) {  $skylight->ParentSet = $this;  // The following is more efficient than array_push();  $this->Skylights[] = $skylight;}

Link to comment
Share on other sites

In Object-oriented programming you cannot add or remove properties from an object, you can just set their values.There is no problem having an object referencing its parent. That's normal and doesn't waste any resources. You just need to be sure to remove the links when you remove an object.
That's what I wanted to know. :)
You shouldn't be cloning the objects, just referencing them.Do this instead:
public function addSkylight($skylight) {  $skylight->ParentSet = $this;  // The following is more efficient than array_push();  $this->Skylights[] = $skylight;}

The only reason I was cloning the object was to remove the array of child references from the parent because I wasn't sure if the recursive reference was good for resources.The way you show me here is the way I originally had it, and in light of your response, the way I am going to use... :)Oh and thanks for the tip about array_push.
As for the private variable. If you are trying to get a private variable then it will stop dead when it sees the variable is private and it's not of the same class, regardless of the value. You may be thinking that an extended class should be able to use private variables but private is strictly for that class only and not even extended classes. You can use protected which works the same way as private but does extend the privilege to sub classes.
No, I know how private/protected/public variables work. I was just uncertain why it still recognized it as a property even after unseting it. After using unset on a public property, it no longer recognizes the property and says "undefined property", but when using unset on a private property it still recognizes the property and says "cannot access private property" instead of "undefined property" as expected.But, since it appears that the recursive reference is not going to be a problem, this issue is no longer important. :P
Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...