No, it is not possible to "undefine" an existing class.
In your case, you should not have several classes that all have the same name : each class should have a different / distinct name, and you should modify the way you are working with those, so your code deals with classes not named ItemClass.
For instance, you could have :
ItemClass_Type1initemclass_type1.phpItemClass_Type2initemclass_type2.php
and so on -- and those classes could all extend the same base class, if needed / if it makes sense.
(For a while, I thought maybe runkit could help with the "undefining a class" idea ; but there doesn't seem to be a function to do that -- and that extension is not quite stable and shouldn't be used on a production server)
No, it is not possible to "undefine" an existing class.
In your case, you should not have several classes that all have the same name : each class should have a different / distinct name, and you should modify the way you are working with those, so your code deals with classes not named ItemClass.
For instance, you could have :
ItemClass_Type1initemclass_type1.phpItemClass_Type2initemclass_type2.php
and so on -- and those classes could all extend the same base class, if needed / if it makes sense.
(For a while, I thought maybe runkit could help with the "undefining a class" idea ; but there doesn't seem to be a function to do that -- and that extension is not quite stable and shouldn't be used on a production server)
No.
Once a class is declared it cannot be 'unset'.
Maybe namespaces could be of use to you?
Take into account that you can't explicitly destroy an object.
The ways to allow PHP Garbage Collector to act upon an object are:
$var = null; // set to null
unset($var); // unset
The object will stay there. However, if you unset the object and your script pushes PHP to the memory limits, the objects not needed will be garbage collected. I would go with unset() as it seams to have better performance (not tested but documented on one of the comments from the PHP official manual).
That said do keep in mind that PHP always destroys the objects as soon as the page is served. So this should only be needed on really long loops and/or heavy intensive pages.
What's wrong with unset($o)? You could wrap that behaviour up in a static class method if it really offends you:
class Foo {
public static function destroy(&$foo) {
unset($foo);
}
}
Foo::destroy($o);
unset($a->new_property);
This works for array elements, variables, and object attributes.
Example:
$a = new stdClass();
$a->new_property = 'foo';
var_export($a); // -> stdClass::__set_state(array('new_property' => 'foo'))
unset($a->new_property);
var_export($a); // -> stdClass::__set_state(array())
This also works specially if you are looping over an object.
unset($object[$key])
Update
Newer versions of PHP throw fatal error Fatal error: Cannot use object of type Object as array as mentioned by @CXJ . In that case you can use brackets instead
unset($object->{$key})
Automatic cleanup?
No, PHP isn't awared about your architecture. It will not remove objects "cascade", they are independent entities - and, more, can belong to different scopes, for example. Simple code:
class Test
{
protected $id = null;
protected $uniqid = null;
public function __construct($id)
{
$this->id = $id;//user-passed variable
$this->uniqid = uniqid();//internal: to identify instance
}
public function getCopy()
{
return new self($this->id);
}
public function getIdentity()
{
return $this->uniqid;
}
}
$foo = new Test(3);
$bar = $foo->getCopy();
var_dump($foo->getIdentity());//valid
unset($foo);
//still valid: bar has nothing to do with foo
var_dump($bar->getIdentity());
By the way, for copying you can use clone in PHP (that, however, will result in object cloning, obviously)
Simple way
Most simple way to resolve a matter is to iterate through $GLOBALS, checking it with instanceof. This has serious weakness: inner function/method scopes would not be affected:
//static since doesn't belong to any instance:
public static function cleanup()
{
foreach($GLOBALS as $name=>$var)
{
if($var instanceof self)
{
unset($GLOBALS[$name]);
}
}
}
-and
$foo = new Test(3);
$bar = $foo->getCopy();
var_dump($foo->getIdentity(), $bar->getIdentity());//valid
Test::cleanup();
//2 x notice:
var_dump($foo, $bar);
Note, that is has nothing to do with "child" mechanics (i.e. it will clean all instances in global scope - no matter which was copied from which).
Common case
Sample above will not do the stuff in common case. Why? Imagine that you'll have holder class:
class Holder
{
protected $obj = null;
public function __construct($obj)
{
$this->obj = $obj;
}
public function getData()
{
return $this->obj;
}
}
and you'll pass instance to it:
$foo = new Test(3);
$bar = $foo->getCopy();
$baz = new Holder($bar);
-so then you'll have no chances to handle even this simple situation in common case. And with more complex situations you will also be stuck.
What to do?
I'd recommend: destroy objects explicitly when you need to do that. Implicit unset is a side-effect, and even if you'll maintain that somehow (I can imagine Observer pattern + some global registry for that) - it will be horrible side-effect, that will kill readability for your code. And same is about code, that uses $GLOBALS I've written above - I do not recommend to act such way in any case.
Try the below code to clear all php objects.
public function clearAllVars()
{
$vars = get_object_vars($this);
foreach($vars as $key => $val)
{
$this->$key = null;
}
}
}
No, you cannot delete or substantially modify PHP classes (or functions) at runtime.
Use unset($classVariableName) to delete the instance and it will free the memory.
If the definition of the class shouldn't be there at run-time, then the class needs to be added in separate file and the file should be included only when it is require. So that you can have two different class definition with same class name. But having two different definition with same name is not a good way to go.
Hey all, I'm trying to learn as much as I can about PHP and the best programming practices for it. I never use PHP's unset() function to unset a variable, because I've never learned if I should or not. Is it generally recommended to unset all variables when they are done use? Do you use unset() in your projects?
I currently use a MVC framework (CodeIgniter) so I guess it would depend on the specific variable about where would be the best place to unset them. Some would be unset in the views, some in the controllers, some in the models.
Any insight you may provide would be highly appreciated. :)
EDIT: People in the comments are saying that it can be a good idea for memory usage / efficiency. However, it is my understand that PHP variables automatically cease to exist once the script is done running. So, would it really help at all with memory usage?