php - unset $this

2019-04-25 11:32发布

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...

6条回答
beautiful°
2楼-- · 2019-04-25 11:46

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楼-- · 2019-04-25 11:47

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>";
查看更多
再贱就再见
4楼-- · 2019-04-25 12:04

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.

查看更多
一夜七次
5楼-- · 2019-04-25 12:06

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

查看更多
时光不老,我们不散
6楼-- · 2019-04-25 12:07

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"

查看更多
冷血范
7楼-- · 2019-04-25 12:09

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.

查看更多
登录 后发表回答