php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #36971 unset() no longer works on $this in PHP5
Submitted: 2006-04-04 19:25 UTC Modified: 2007-08-20 12:11 UTC
Votes:6
Avg. Score:4.0 ± 0.8
Reproduced:6 of 6 (100.0%)
Same Version:5 (83.3%)
Same OS:2 (33.3%)
From: k at phpkoala dot com Assigned:
Status: Closed Package: Documentation problem
PHP Version: 5.1.2 OS: Linux
Private report: No CVE-ID: None
 [2006-04-04 19:25 UTC] k at phpkoala dot com
Description:
------------
In PHP4, calling unset($this) within a class worked fine, and destroyed that class instance. This was a very useful way technique, one that I and others have used many times.

In PHP5, it simply no longer works. There is no error message - not even a strict - the instance is just unaffected.

PHP4 also offers another method - setting $this = NULL, but PHP5 gives an error that $this cannot be reassigned.

I would like to see this functionality restored, or, an alternate mechanism for destroying class instances internally should be pointed out (and put into the manual), or, if for some unknown reason this useful functionality is now declared by the PHP staff to be evil, the reasons should be revealed and the appropriate details put into the manual so that we know it know longer works in PHP5, and why.

I figure it's just a bug ;)

Reproduce code:
---------------
class test {
	function f1() {
		unset($this);
	}
	function f2() {
		$this = NULL;
	}
}

$obj = new test;
var_dump($obj);

$obj->f1();
var_dump($obj);

$obj->f2();
var_dump($obj);

unset($obj);
var_dump($obj);

Expected result:
----------------
object(test)(0) {
}
NULL
NULL
NULL

Note: if f1() worked, there would be no need to run f2(), because $obj would have been unset. But, both methods should result in $obj being NULL.

OR:

object(test)(0) {
}
object(test)(0) {
}
NULL
NULL

This would also be an acceptable result, because there is an alternate method (f2()) that can be used. This is the result from the latest version of PHP4.

Actual result:
--------------
From PHP5:

Fatal error: Cannot re-assign $this in /home/test2.php on line 6

So, f2(), which sets $this to NULL, doesn't work. Commenting that out produces:

object(test)#1 (0) {
}
object(test)#1 (0) {
}
NULL

So, neither of the methods f1() or f2() work.


From the latest version of PHP4:

object(test)(0) {
}
object(test)(0) {
}
NULL
NULL

This is fine, as the desired effect can still be accomplished.


In earlier versions of PHP4, both f1() and f2() work fine.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-04-04 19:33 UTC] mike@php.net
I can't believe you're serious.
 [2006-04-04 23:18 UTC] k at phpkoala dot com
Mike, I am serious or I would not have taken the time to post this bug report.

The manual page for unset, over at http://www.php.net/manual/en/function.unset.php, does not mention this change in functionality. Like I said in my first message, this is something that works in PHP4 but no longer works in PHP5.

If you can't believe I am serious, please point out why you think this is a joke? How do you destroy a class instance internally in PHP5? And if this is never going to happen, can't you say this in the manual, along with an explanation?

If nothing else, the very fact that it worked in PHP4 and does not work in PHP5 should merit a mention in the documentation. (Just Google for this issue and you will see many pieces of software that have broken because of this, when used on PHP5.)

Back to you, Mike.
 [2006-04-04 23:53 UTC] scottmacvicar at ntlworld dot com
Destroying an object internally is an absurd concept, how can you destroy something that is currently in the scope of execution?

The reason it works in PHP 4 and not in PHP 5 is that object types are no longer mutable.
 [2006-04-05 06:21 UTC] derick@php.net
@Scott: totally true.

This can ofcourse be mentioned in the documentation if it's not already there...
 [2006-04-05 19:04 UTC] k at phpkoala dot com
Thanks Scott, that makes sense.

Does that mean there is no way to accomplish this in PHP5? I guess so.

I'd like to see this added to the docs.
 [2006-05-04 10:31 UTC] gixxman at gmali dot com
class FalseClass
{
	public function __destruct()
	{
		echo "Gonna die, man";
	}
}

$f = new FalseClass;
unset($f);


RESULTS:

Gonna die, man
 [2006-06-18 19:21 UTC] henke dot andersson at comhem dot se
In php5 no php variable actualy contains the object instances, they contains pointers to instances. Thats why unseting the $this variable does nothing. Just because you stop knowing where it is doesn't mean it ceases to exist.
And the $this variable is a special case. It would not make sence to unset it.
As far as I can understand, $this shouldn't even affect the garbage collection, if it did(and php doesn't adjust for recurive pointers) the garbage collection would never destroy objects instances!
 [2006-07-06 15:41 UTC] keko_metal at hotmail dot com
Scott, do you really think that
$object->im_done_please_kill_me() is an absurd idea?
 [2006-07-06 15:52 UTC] leszek@php.net
It's absurd (well, maybe not absurd, but not needed) as long as PHP has destructor methods.
 [2007-04-06 20:41 UTC] joel at propbot dot com
The problem comes into mind when your creating an object and going 
through a loop. The script just grows and grows until your out of 
memory.

We are creating an object doing what we need to do with it and trying 
to destroy it. Anybody have a solution?
I really don't want to have to go through every variable inside the 
object and do an unset().
 [2007-04-07 01:10 UTC] edwardzyang at thewritingpot dot com
It's tough to understand what your problem is without more code. If you are doing:

for ($i = 0; $i < 1000000; $i++) {
  $obj = new Foo();
  // do stuff with $obj
  unset($obj);
}

That should be sufficient. Could you be more specific?

Usually, if the PHP interpreter is running out of memory, you've got some bad code that needs refactoring.
 [2007-07-18 13:53 UTC] scott at utnow dot com
This is really quite simple to understand folks...  

The guy has a class that is sitting there doing it's thing.
He has a function (say it's 'DestroyMe') that should do simply that.

The best case I can imagine...

The class is 'object' and it interfaces with a row in a table in a 
database.

If you're going to delete the object's row from the table, it probably 
makes sense to destroy the class handling it.

function destroy() { delete row; destruct class; }

Thus it would be helpful to be able to do what he's asking.

Now whether it fits within the realm of responsible coding or not I'm 
not the judge...  lol
 [2007-08-20 12:11 UTC] vrana@php.net
This bug has been fixed in the documentation's XML sources. Since the
online and downloadable versions of the documentation need some time
to get updated, we would like to ask you to be a bit patient.

Thank you for the report, and for helping us make our documentation better.

"It is not possible to unset $this inside an object method since PHP 5."
 [2011-09-20 15:48 UTC] james at esilogix dot com
I have an object Criteria.  It has a method apply().  I would like to pass an object to apply() by reference, and if it does not satisfy the criteria, I would like Criteria->apply() to be able to destroy the object.

I've tried unset, I've tried object->destroy() with "unset($this)", doesn't work.  I can set it to null, but then I have a null object in my collection, and I don't want that.
 [2013-01-14 21:53 UTC] hujuice at inservibile dot org
A very old problem.
I'm managing exactly a scenario like the one told by scott in 2007-07-18 13:53 UTC

My objects MUST match with database rows, via object methods.
$myObj->load($id); // SELECT
$myObj->save(); // INSERT/UPDATE
$myObj->delete(); // DELETE

But when I call the delete() function my objects lose their sense.
I feel that the original requirement is not so strange.

I understand that changing type is quite absurd, but now I need to introduce checks to establish if the object is still alive.

A native solution could be appreciated.

Regards,
HUjuice
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Mon Dec 30 20:01:28 2024 UTC