How to destroy an object?
Asked Answered
S

6

140

As far as I know (which is very little) , there are two ways, given:

$var = new object()

Then:

// Method 1: Set to null
$var = null;
// Method 2: Unset 
unset($var); 

Other better method? Am I splitting hairs here?

Stepson answered 10/1, 2012 at 4:9 Comment(0)
B
171

You're looking for unset().

But take into account that you can't explicitly destroy an object.

It 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 opposed to setting it to null) as it seems 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.

Basque answered 10/1, 2012 at 4:11 Comment(9)
So Frankie, I come from C++, where when we use new once, then we must use delete once. This is not true in PHP? There is automatic garbage collection when the object is no longer needed?Hysteroid
@Hysteroid that's true. You can also have leaks, though, and you should read more on php's GC if you're doing daemons or similar. In the majority of sites the request is so short lived that it doesn't matter. php.net/manual/en/features.gc.refcounting-basics.phpBasque
Does unset() removes the reference to the Object?Tara
does this answere still stand in 2021? it is needed for UnitTesting, a concept not really far spread in 2012 i assumeWaziristan
unset might be useful for background CLI workers which normally stay active in background until they are explicitly terminated or restarted.Folly
What about the same variable being reused inside a loop (for instance $mp3 = new MP3File($filename);)? Will unset() in the end of the block make a difference here?Rouen
@Rouen I would suggest you check with memory_get_usage() inside that loop as it really depends on what extra things you're doing in the loop and how much memory you actually need. You can't really control when php calls free and mallocs. Re-using the variable, in theory, would mean memory space would not have to be re-allocated, symbol table entry would not have to be re-created and corresponding management object. But this is not always the case.Basque
does unset() make PHP to call __destruct() magic method?Rowles
@DeividAs check here what happens if you unset a class with a destructor: onlinephp.io/c/012b8Basque
I
10

A handy post explaining several mis-understandings about this:

Don't Call The Destructor explicitly

This covers several misconceptions about how the destructor works. Calling it explicitly will not actually destroy your variable, according to the PHP5 doc:

PHP 5 introduces a destructor concept similar to that of other object-oriented languages, such as C++. The destructor method will be called as soon as there are no other references to a particular object, or in any order during the shutdown sequence.

The post above does state that setting the variable to null can work in some cases, as long as nothing else is pointing to the allocated memory.

Illyricum answered 11/2, 2014 at 17:13 Comment(0)
C
5

Short answer: Both are needed.

I feel like the right answer was given but minimally. Yeah generally unset() is best for "speed", but if you want to reclaim memory immediately (at the cost of CPU) should want to use null.

Like others mentioned, setting to null doesn't mean everything is reclaimed, you can have shared memory (uncloned) objects that will prevent destruction of the object. Moreover, like others have said, you can't "destroy" the objects explicitly anyway so you shouldn't try to do it anyway.

You will need to figure out which is best for you. Also you can use __destruct() for an object which will be called on unset or null but it should be used carefully and like others said, never be called directly!

see:

http://www.stoimen.com/blog/2011/11/14/php-dont-call-the-destructor-explicitly/

What is difference between assigning NULL and unset?

Capriccioso answered 18/4, 2018 at 16:2 Comment(0)
G
1

May be in a situation where you are creating a new mysqli object.

$MyConnection = new mysqli($hn, $un, $pw, $db);

but even after you close the object

$MyConnection->close();

if you will use print_r() to check the contents of $MyConnection, you will get an error as below:

Error:
mysqli Object

Warning: print_r(): Property access is not allowed yet in /path/to/program on line ..
( [affected_rows] => [client_info] => [client_version] =>.................)

in which case you can't use unlink() because unlink() will require a path name string but in this case $MyConnection is an Object.

So you have another choice of setting its value to null:

$MyConnection = null;

now things go right, as you have expected. You don't have any content inside the variable $MyConnection as well as you already cleaned up the mysqli Object.

It's a recommended practice to close the Object before setting the value of your variable to null.

Gautea answered 26/10, 2018 at 16:44 Comment(0)
H
0

In PHP you are not destroying an object, you are destroying a pointer to the object. It is a big difference.

In other languages you can destroy an object and all the other pointers will give you exceptions or rubbish, but it is not a case for PHP.

This is a simple prove that you cannot destroy an object, you can only destroy a link to it.

$var = (object)['a'=>1];
$var2 = $var;
$var2->a = 2;
unset($var2);
echo $var->a;

returns

2

See it in action here: https://eval.in/1054130

Hornstone answered 5/9, 2018 at 7:21 Comment(4)
Right, you've destroyed $var2 which was a reference to $var. Now you destroy $var as well and, presuming there are no other references holding on the object, you're done.Wards
You are not destroying an object, you are destroying a pointer to the object. It is a big difference.Hornstone
In other languages you can destroy an object and all the other pointers will give you exceptions or rubbish, but it is not a case for phpHornstone
You cannot destroy. If there is no reference holding the object, the object is ready to be collected by the garbage collector. And you cannot force to run the garbage collector.Therefor
B
-9

I would go with unset because it might give the garbage collector a better hint so that the memory can be available again sooner. Be careful that any things the object points to either have other references or get unset first or you really will have to wait on the garbage collector since there would then be no handles to them.

Baleen answered 10/1, 2012 at 4:13 Comment(2)
Unless you actually have sources to back up your answers, you probably shouldn't post what you think "might" happen. It's not useful and leads to this sort of misinformation being taken as truth and repeated.Marrero
@meagar that is the exact reason why I linked to the official manual page where, in the comments, there is a sample test comparing unset() to null.Basque

© 2022 - 2024 — McMap. All rights reserved.