Search code examples
phpobjectruntimeunset

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


I'm having a class that has a property which I want to unset/destroy during runtime. The unsetting happens in a specific method, but the method that calls it returns TRUE in property_exists, while it can't directly access the property with $this->property as it returns a notice Notice: 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;
  }

As you can see in the code after the unsetting, the property_exists returns TRUE which shouldn't happen, but the property is undefined.

EDIT

It seems that if the property is declared in class' schema then it cannot be destroyed/unset (see selected answer's demo) and in fact it behaves paradoxically: property_exists => TRUE, object->property => warning

BUT when the property is not defined but created at object's construction, then it can be unset and behave as expected.


Solution

  • It seems as of PHP 5.3.0 that if you define it as an object variable then property_exists returns true even after unset. Use isset($this->isEmpty) instead as this returns false after unset.

    See the differences: Demo

    However, you should probably take a different approach like setting to true or false or null or something and checking that.

    Demo Code:

    <?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();