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