如何在运行时正确取消设置PHP中的类属性?

How to properly unset a class property in PHP during runtime?

提问人:Chris Athanasiadis 提问时间:4/10/2019 最后编辑:Chris Athanasiadis 更新时间:11/17/2023 访问量:695

问:

我有一个类,它有一个属性,我想在运行时取消设置/销毁该属性。取消设置发生在特定方法中,但调用它的方法返回 ,而它不能直接访问属性,因为它返回通知TRUEproperty_exists$this->propertyNotice: Undefined property:...


  public function get(int $id) {
    if ($record->data) {
      $this->_transform($record); //  Calling method that unsets prop
    }    

    if (! property_exists($this, 'isEmpty') ) { //  FALSE
      $this->transform();
    }else{
      echo $this->isEmpty; //  FALSE as well!
    }

    return $this;
  }

  private method _transform(Record $record) {
    unset($this->isEmpty); //  Unsetting happens here

    return;
  }

正如您在取消设置后的代码中看到的那样,返回 TRUE,这不应该发生,但属性未定义。property_exists

编辑

似乎如果该属性是在类的模式中声明的,那么它就无法被销毁/取消设置(请参阅所选答案的演示),实际上它的行为是矛盾的:property_exists => TRUE,object->property =>警告

但是,如果属性不是定义的,而是在对象构造时创建的,则可以取消设置它并按预期运行。

PHP 对象 运行时 未设置

评论


答:

0赞 AbraCadaver 4/10/2019 #1

似乎从 PHP 5.3.0 开始,如果您将其定义为对象变量,则即使在 .请改用,因为这在 之后返回。property_existstrueunsetisset($this->isEmpty)falseunset

查看差异: 演示

但是,您可能应该采取不同的方法,例如设置为 or or or 或其他东西并检查它。truefalsenull

演示代码:

<?php

class test {

    public function a(){
        $this->isEmpty = 1;
        var_dump(property_exists($this, 'isEmpty'));
        unset($this->isEmpty);
        var_dump(property_exists($this, 'isEmpty'));
    }
}
$t = new test();
$t->a();

class test2 {
    public $isEmpty;
    
    public function a(){
        $this->isEmpty = 1;
        var_dump(property_exists($this, 'isEmpty'));
        unset($this->isEmpty);
        var_dump(property_exists($this, 'isEmpty'));
    }
}
$t = new test2();
$t->a();

class test3 {
    public $isEmpty;
    
    public function a(){
        $this->isEmpty = 1;
        var_dump(isset($this->isEmpty));
        unset($this->isEmpty);
        var_dump(isset($this->isEmpty));
    }
}
$t = new test3();
$t->a();

评论

0赞 Chris Athanasiadis 4/10/2019
是的,问题在于property_exists返回 TRUE,而直接访问返回警告,这是自相矛盾的。一种解决方案是采用不同的方法,而另一种解决方案,我刚刚发现,关于您的示例,不是在类中定义属性,而是在运行时创建它,它的行为符合预期。
0赞 Chris Athanasiadis 4/10/2019
如果您想扩展您的答案,请说如果按照演示中的 #1 示例在对象构造之后定义属性,则可以实现它。谢谢
0赞 Reed 11/17/2023
我在答案中添加了演示代码,以防链接中断。如果您不同意,请将其删除,没什么大不了的。