<?php
class a{
    public function out(){
        $this->test = 8;
        return $this->test;
    }
}
$b = new a();
echo $b->out();
?>
output: 8
when i run this code, output the result 8 .
but when i add __set() function, it output a notice, and not 8 output
<?php
class a{
    public function __set($property, $value) {  
    }
    public function out(){
        $this->test = 8;
        return $this->test;
    }
}
$b = new a();
echo $b->out();
?>
output:
PHP Notice: Undefined property: a::$test in /usercode/file.php on line 13
why is it happening?
As per the docs
__set() is run when writing data to inaccessible properties.
Since you do not have anything in your __set body, the property is not created and therefore not available. You have to define the method body.
class a{
    public function __set($property, $value) {
        $this->$property = $value;
    }
    public function out(){
        $this->test = 8;
        return $this->test;
    }
}
$b = new a();
echo $b->out();
Now THAT outputs 8.
Update You are asking why the first block of code works and the second does not. Take a look at PHP source code here and you will see the explanation in the code itself.
Looks to me, that when you do not have __set() in your class and you do $this->test, PHP internally calls it's own __set(), which does exactly what it does: sets the property name to certain value.
But when you define __set() with empty body, it overrides the default internal __set() and does nothing. And that is the main reason for your code to fail - the requested property has not been set neither by your __set(), nor by the internal one.
When a::out() runs, there is no $test property in the object. This is why $this->test = 8; invokes a::__set().
But a::__set() doesn't create the $test property and the next statement (return $this->test;) cannot find it and produces the notice.
You should declare the object properties in the class definition and initialize them in the constructor (if appropriate):
class a {
    private $test;               // <-- because of this, $this->test exists...
    public function __set($property, $value) {  
    }
    public function out() {
        $this->test = 8;         // ... and __set() is not invoked here
        return $this->test;
    }
}
Without __set() being defined, the statement $this->test = 8; creates the $test property of the current object if it is not already created (by its definition or by a previous assignment to it) then stores 8 into it.
When __set() is defined, any attempt to set a property that doesn't exist or it is not accessible (setting inside the class a private property inherited from the parent class or setting a protected or private property outside the class) is handled by __set(). Your implementation of __set() doesn't create the missing property and it basically turns the statement $this->test = 8; into a no-op.
The following is true.
<?php
class a{
    public function __set($property, $value) {
        $this->$property = $value;
    }
    public function out(){
        $this->test = 8;
        return $this->test;
    } 
}
$b = new a();
echo $b->out();  
you should look at is php overloading
Find the answers in the manual.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With