Search code examples
phpgetsetmagic-methods

__set() method echoing property value twice


I am new to php world.I am trying to understand how __set() magic method works in php.Here i create a new property using __set() method.I have a if statement which checks for whether the property is already exists or not.If not exists ,then it creates the property and assign it a value.Here i am checking for two properties.They are $newProp and $anotherProp . $newProp doesn't exists.So it creates the property and echoing it's value twice.But for $anotherProp,which already exists,The else condition didn't trigger.Here i am facing two problem

1.It's echoing the property value twice.

2.Else condition is not working at all.I mean if property already exists it doesn't print any message.

      class myclass {

        public $anotherProp='Another property value';

        public function __set($prop,$val){
           if(! property_exists($this,$prop) ){

              $this->prop=$val;
              echo $this->prop;

           }else{
              echo 'property already exists';
           }
        }
}

$obj=new myclass();

$obj->newProp='i am a new property';

$obj->anotherProp='i am another property';

Solution

  • In your __set() you are accidentally creating yet another public property called $this->prop implicitly because you don't use the variable $prop to determine which property gets its value set. The subsequent echo happened twice because that as-yet-uncreated property called __set().

    Use $this->$prop to solve that part of it, and have a look at the PHP documentation on "variable variables", where you'll find examples for variable object properties.

    public function __set($prop, $val) {
      if (!property_exists($this, $prop)) {
        // Set the property dynamically
        $this->$prop = $val;
        echo $this->$prop;
      }
      else {
        echo 'property already exists';
      }
    }
    

    Now the reason you don't see property already exists when calling it on $anotherProp is because __set() is called for inaccessible properties. It is not called for properties declared public. If you instead declare

    private $anotherProp = 'i am another property';
    

    you will see the __set() method called and the already exists message printed.

    Here's the whole thing in action