136

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?

Script47
  • 14,230
  • 4
  • 45
  • 66
PandemoniumSyndicate
  • 2,855
  • 6
  • 29
  • 49

6 Answers6

170

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.

Jeff Puckett
  • 37,464
  • 17
  • 118
  • 167
Frankie
  • 24,627
  • 10
  • 79
  • 121
  • 1
    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? – gsamaras Sep 11 '15 at 01:13
  • 3
    @gsamaras 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. http://php.net/manual/en/features.gc.refcounting-basics.php – Frankie Sep 11 '15 at 11:38
  • 1
    Does `unset()` removes the reference to the Object? – Yousha Aleayoub Aug 10 '17 at 22:00
  • does this answere still stand in 2021? it is needed for UnitTesting, a concept not really far spread in 2012 i assume – clockw0rk May 04 '21 at 12:56
  • unset might be useful for background CLI workers which normally stay active in background until they are explicitly terminated or restarted. – Penuel Jun 13 '22 at 06:05
9

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.

Community
  • 1
  • 1
sturrockad
  • 4,460
  • 2
  • 19
  • 19
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?

Mike Q
  • 6,716
  • 5
  • 55
  • 62
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.

Karsten Koop
  • 2,475
  • 1
  • 18
  • 23
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

Yevgeniy Afanasyev
  • 37,872
  • 26
  • 173
  • 191
  • 3
    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. – i336_ Sep 16 '18 at 03:11
  • 7
    You are not destroying an object, you are destroying a pointer to the object. It is a big difference. – Yevgeniy Afanasyev Sep 16 '18 at 09:21
  • 1
    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 – Yevgeniy Afanasyev Sep 16 '18 at 09:23
  • 1
    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. – Daniel Dec 20 '19 at 14:52
-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.

hackartist
  • 5,172
  • 4
  • 33
  • 48
  • 17
    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. – user229044 Jan 10 '12 at 04:24
  • 1
    @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. – Frankie Jan 10 '12 at 04:36