【问题标题】:php - unset $thisphp - 取消设置 $this
【发布时间】:2011-04-24 20:04:52
【问题描述】:

我创建了一个类似于文件包装器的类。当用户调用删除方法时,我想取消设置对象(实际上是 $this)。有没有办法(解决方法)做到这一点?说明书上说不行,没办法……

【问题讨论】:

  • 你能提供你想调用它的代码吗?没有上下文,您的问题非常不清楚
  • 您真的需要取消设置对象吗?我有这种感觉,有另一种方法可以做你想做的事。也许如果你发布了一些代码......

标签: php file wrapper this unset


【解决方案1】:

如果你有课

class XXX
{

....

}

你有对象

$obj = new XXX();

你可以使用 unset() 函数来删除对象

unset($obj);

【讨论】:

    【解决方案2】:

    我花了很多时间寻找一种方法,从它自身内部将一个对象设置为 NULL。

    请试试这个代码:

    <?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>";
    ?>
    

    诀窍是 $this 不起作用,您需要通过对类的引用将实际引用传递给它。

    另一种访问实际引用而不传递它的方法是将对象定义为全局对象:

    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>";
    

    【讨论】:

    • 第二个是坏版本,这意味着你应该只为对象使用 isRide 名称
    【解决方案3】:

    我和你有同样的问题,在某些时候我想让对象自己删除,但在 php 中是不可能的,所以这是一个可能对你有帮助的解决方法。

    您可以设置一个私有标志并在每个需要该对象的方法中检查该标志是否仍然存在,例如:

    <?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
        }
    
    }
    
    ?>
    

    其他方法可能是重载 _call 方法并在调用该方法之前查看标志,这也可能需要使用一些前缀重命名方法,例如“pub”,以便在 __call 方法中进行调用.这是一个例子:

    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 !!!
    
    ?>
    

    恕我直言,对象无法将自己从内存中删除是一个真正的问题,但这是 PHP 设计的一部分,它不是 C++。作为左派的想法,对于这个和其他事情,您可以在其他语言/库中传递应用程序的逻辑,这些语言/库是用 C++/C# 等其他语言开发的,并使用 PHP 来使用该逻辑,例如“HTML/CSS/JS/PlainText PHP C# Cli 数据库/文件/存储"

    【讨论】:

      【解决方案4】:

      嗯,不,只有反过来,你才能使用神奇的 __destruct() 函数:

       public function  __destruct() {
          //delete file
       }
      

      当脚本结束时有人 unset() 对象 AND 时会触发此事件。但是 Object 不能自我毁灭。

      【讨论】:

        【解决方案5】:

        手册是对的。没办法。

        unset 本质上用于表示“我已经使用完一个特定变量;就我而言,它可以考虑用于垃圾回收

        问题在于$this 无论如何只在方法调用的上下文中才有意义。一旦该方法完成,$this 将(本质上)超出范围,并且不再算作对该对象的引用。 (出于实际目的。)

        因此您无需担心释放$this。 PHP 会解决这个问题。

        您可能尝试做的是unset 可能引用同一实例的其他 变量。除非您可以从方法中访问它们,否则您无法触摸它们,更不用说unset 它们了。

        【讨论】:

          【解决方案6】:

          如果您想同时删除对象及其包装的文件,请将您的删除代码放入析构函数中。然后只需unset 对象而不是调用删除方法。

          【讨论】:

          • 我也想过这个,但是它会在脚本执行结束时自动删除文件:) 似乎没有办法区分显式unset和脚本结束.
          • 那么运气不好。您只需要使用 2 个电话 -&gt;delete(),然后是 unset。或者重新考虑你的设计。
          【解决方案7】:

          据我所知,没有办法从类本身中销毁类实例。您必须在其范围内取消设置实例。

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

          有点相关:执行上述操作将自动调用该类的任何现有 __destruct() 魔术方法,因此您可以进行任何额外的清理。 More info

          【讨论】:

            猜你喜欢
            • 2018-07-20
            • 1970-01-01
            • 2012-09-11
            • 2014-03-25
            • 2010-12-30
            • 1970-01-01
            • 2011-05-23
            • 2014-07-18
            • 1970-01-01
            相关资源
            最近更新 更多