I know that for some that might sound stupid, but I was thinking if I hava a delete() method in a class that removes all the object data (from DB and file system), how can I destroy/remove the object from within the class.
This is a PHP question. Something like unset($this);
Is it possible and wise? And what is the right way to do it?
There is a __destruct() magic method which is a destructor for a PHP Class.
Maybe you can put your deletion code in there and as soon as all reference to your objects are deleted, this destructor will be called and the data deleted.
Here is a sample solution which would be "reasonably usable" when implemented in well defined relationship/reference patterns, usually I drop something like this in my composites. To actually use the current code as I've done in this example in a real life would be going through too much trouble but it's just to illustrate the how-to-point.
An object can't just magically disappear - it will only be deleted (garbage collected) once there is nothing pointing at it. So "all" an object has to do is to keep track of everything that refers to it. It is fairly low friction when you have all the reference management built in - objects are created and passed on only by fixed methods.
Lets begin with a simple interface so we would be able to tell if it is safe to pass our reference to an object or not.
A class which can safely hold a reference to our object.
And finally a class with the ability to self-destruct aka trigger the process of being removed by all of its parents.
And for the example of usage, holding the reference in an
array
, in anobject
implementing ourinterface
and the$GLOBALS array
.Output:
This depends on how you've structured your class.
If you're following DTO/DAO patterns, your data would be separate from your model and you can simply remove the DTO. If you're not, simply unsetting the data part of the class should do it.
But in actual terms, I think this is unnecessary since PHP will automatically cleanup at the end of the request. Unless you're working on a giant object that takes up massive amounts of memory, and it's a long process it's not really worth the effort.
You cannot unset
$this
. Or more correctly:unset()
on$this
only has local effect on the variable.unset()
removes the variable from the local scope, which reduces the ref count for the object. If the object is still referenced somewhere else, it will stay in memory and work.Typically, the value of an ID property is used to determine if an object is stored in the back end. If the ID has a proper value, that object is stored. If the ID is
null
, it is not stored, yet. On successful storage you then set the ID accordingly. On delete you set the ID property tonull
again.Whilst developing on a framework, I came across such issue as well.
unset($this)
is totally not possible, as$this
is just a special pointer that allows you to access the current object's properties and methods.The only way is to encapsulate the use of objects in methods / functions so that when the method / function ends, the reference to the object is lost and garbage collector will automatically free the memory for other things.
See example
RaiseFile
, a class that represents a file:In the RaiseFile class, it'll be sensible that after you call the
delete()
method and the file is deleted, the RaiseFile object should also be deleted.However because of the problem you mentioned, I actually have to insist that RaiseFile points to a file whether or not the file exists or not. Existence of the file can be tracked through the
exists()
method.Say we have a cut-paste function that uses RaiseFile representation:
Notice how
$f
is removed and GC-ed after the function ends because there is no more references to theRaiseFile
object$f
outside the function.I'm in this same boat now.
I'm building a CMS solution from the ground up and have a lot of references between objects; users, groups, categories, forums, topics, posts, etc.
I also use an "Object::getObject(id)" loader in each class which ensures there's only one instance of an object per ID, but also means it's even easier for code to pull a reference to existing objects.
When the data the object represents gets deleted from the data source, I'd like to wipe the object from memory and nullify all references to it to ensure other code doesn't try to use an obsolete data set.
Ideally all references should be removed--the referencing code can provide a callback that gets fired at object deletion that can subsequently remove/update the reference. But if the referencing code gets sloppy, I'd rather it error out with a "Not an object" error than actually work with the object.
Without knowing how to force the destruction from within the object, itself, I'm being forced to:
Begin almost every non-static method with a check to see if the object has been flagged "deleted", throwing an exception if it is. This ensures any referencing code can't do any harm, but it's a nasty thing to look at in the code.
Unset every object variable after deletion from the database, so it doesn't linger in memory. Not a big deal but, again: nasty to look at.
Neither would be needed if I could just destroy the object from within.