7Answers

php - unset $this

8.3k Views
  • 3
name

A PHP Error was encountered

Severity: Notice

Message: Undefined index: userid

Filename: views/question.php

Line Number: 191

Backtrace:

File: /home/prodcxja/public_html/questions/application/views/question.php
Line: 191
Function: _error_handler

File: /home/prodcxja/public_html/questions/application/controllers/Questions.php
Line: 433
Function: view

File: /home/prodcxja/public_html/questions/index.php
Line: 315
Function: require_once

name Punditsdkoslkdosdkoskdo

php - unset $this

I've made a class that acts like an file wrapper. When user call delete method, i want to unset the object (actually $this). Is there a way (workaround) to do that? The manual said no, there is no way...

      • 2
    • Could you provide code where you want to call this? Your question is very unclear without a context
      • 1
    • Do you really NEED to unset the object? I get this feeling that there's another way to do what you want. Maybe if you posted some code...

As far as I know, there is no way to destroy a class instance from within the class itself. You'll have to unset the instance within its scope.

$myClass = new fooBar();
unset($myClass);

Somewhat related: Doing the above will automatically call any existing __destruct() magic method of the class so you can do any additional cleanup. More info

  • 11
Reply Report

The manual is right. There is no way.

unset is used essentially to say "I'm finished using a particular variable; it can be considered for garbage collection as far as I'm concerned.

The trouble is that $this only makes sense in the context of a method call anyway. Once the method completes, $this will fall out of scope (essentially) and will no longer count as a reference to the object. (For practical purposes.)

So you don't need to worry about freeing up $this. PHP will take care of that.

What you're probably trying to do is unset the other variables that might reference the same instance. And unless you have access to those from within the method, you can't touch them, much less unset them.

  • 3
Reply Report

I spent a lot of time finding a way of setting to NULL an object from within it's self.

Please try this code:

<?php
class bike{
    public $color = "black";
    function destroySelf(bike &$me){
        $me = NULL;
        //$me = new bike();
    }
}
$iRide = new bike();
$iRide->color = "red";
var_dump($iRide);echo " -before <br>";
$iRide->destroySelf($iRide);
var_dump($iRide);echo " -after <br>";
?>

Trick is $this won't work, you need to pass it the actual reference by reference to the class.

Another way to access the actual reference without passing it is defining the object as a global:

class bike{
    public $color = "black";
    function destroySelf(){
        global $iRide;
        $iRide = NULL;
        //$iRide = new bike();
    }
}
$iRide = new bike();
$iRide->color = "red";
var_dump($iRide);echo " -before <br>";
$iRide->destroySelf();
var_dump($iRide);echo " -after <br>";
  • 1
Reply Report

Put your delete code in the destructor if you want to get rid of the object and the file it wraps at the same time. Then just unset the object instead of calling a delete method.

  • 0
Reply Report
      • 2
    • I thought of this too, but it will delete the file automatically at the end of the script's execution :) There seems to be no way to distinguish between an explicit unset and the end of the script.

Well, No, only the other way around, you can use the magic __destruct() function:

 public function  __destruct() {
    //delete file
 }

This will be triggered when someone unset() the Object AND when the script ends. But an Object can't destroy itself.

  • 0
Reply Report

I has the same problem as you, in some point I want to make the object remove itself but it isn't possible in php, so this is a workaround that may help you.

You can setup a private flag and check that flag in every method that require the object still exists, something like:

<?php

class Bar {
    // internal flag
    private $_removed = false;

    public function remove() {
        // ... some code
        $this->_removed = true;
    }

    private function checkExceptionRemoved() {
        if ($this->_removed) throw new RuntimeException("The object has been removed");
    }

    public function show() {
        $this->checkExceptionRemoved();
        // ... some code
    }

}

?>

Other way could be overloading the _call method and review the flag before calling the method, this also may require renaming the methods with some prefix like "pub" to make the call inside the __call method. This is an example:

class Foo {
    private $_value;
    private $_valid = true;

    public function IsValid() {
        return $this->_valid;
    }

    private function IsValidException() {
        if (!$this->IsValid()) throw new RuntimeException("The object has been removed");
    }

    public function __construct($value) {
        $this->_value = $value;
    }

    public function __call($name, $arguments) {
        if (!$this->IsValid()) throw new RuntimeException("The object has been removed");
        if (!method_exists($this, "_$name")) throw new Exception("Invalid call, method '$name' does not exists");
        return call_user_func_array(array($this, "_$name"), $arguments);
    }

    protected function _show() {
        echo print_r($this->_value, true)."\n";
    }

    protected function _remove() {
        $this->_valid = false; 
    }
}


$foo = new Foo("Foo Object");
$foo->show();
$foo->remove();
$foo->show(); // Exception !!!

?>

IMHO it's a real problem that an object cannot remove itself from memory, but it's part of the design of PHP, it's not C++. As a left thought, for this and other things, you could relay the logic of the application in other language/libraries developed in other languages like C++/C# and use PHP to consume that logic, something like "HTML/CSS/JS/PlainText <-> PHP <-> C# Cli <-> DB/Files/Storage"

  • 0
Reply Report

Warm tip !!!

This article is reproduced from Stack Exchange / Stack Overflow, please click

Trending Tags

Related Questions