Reputation: 2768
<?php
class BaseClass {
protected $data = array("foo" => 0, "bar" => 0, "baz" => 0);
public function __set($name, $value) {
if( array_key_exists($name, $this->data)){
$func = "set_$name";
return call_user_func_array(array($this,$func),array($value));
}
}
public function __get($name) {
if ( array_key_exists($name, $this->data)){
$func = "get_$name";
return call_user_func_array(array($this,$func),array());
}
}
public function __call($method, $args) {
if (method_exists($this,$method)) {
return call_user_func_array(array($this,$method),$args);
}
if (substr($method, 0, 4) == 'set_'){
$var_name = substr($method, 4);
if (!(array_key_exists($var_name, $this->data))){
return FALSE;
}
$this->data[$var_name] = $args[0];
return TRUE;
}
if (substr($method, 0, 4) == 'get_'){
$var_name = substr($method, 4);
if (!(array_key_exists($var_name, $this->data))){
return FALSE;
}
return $this->data[$var_name];
}
}
}
class SubClass extends BaseClass {
protected $baz_changed = FALSE;
public function set_baz($value) {
if ($value != $this->baz){
print "\n\nthis->data BEFORE SET: ";
print_r($this->data);
print "\n\nthis->baz: ";
print_r($this->baz);
print "\n\nPASSED baz: ";
print_r($value);
$this->baz = $value;
print "\n\nbaz AFTER SET: ";
print_r($this->baz); // appears it was set
print "\n\nDATA ARRAY: ";
print_r($this->data); // but it wasn't ... what gives?
$this->baz_changed = TRUE;
}
}
}
$sc = new SubClass();
$sc->foo = 1;
print "\n\$sc->foo = $sc->foo\n";
$sc->baz = 5;
print "\$sc->baz = $sc->baz\n";
?>
I get the following results are not as I would have expected:
$sc->foo = 1
this->data BEFORE SET: Array (
[foo] => 1
[bar] => 0
[baz] => 0 )
this->baz: 0
PASSED baz: 5
baz AFTER SET: 5
DATA ARRAY: Array (
[foo] => 1
[bar] => 0
[baz] => 0 ) $sc->baz = 5
As you can see, it appears that baz is set but it never gets set in the data array. Can anyone explain why and how to fix this?
EDIT: Fixed formatting of the results and adding more context to this code section because stackoverflow is complaining I do not have enough.
EDIT: Just noticed that at the end it says $sc->baz = 5. But the data array isn't updated. This is not expected I would rather that the data array version of baz were updated. Instead of a new instance variable created in SubClass.
Upvotes: 0
Views: 321
Reputation: 3848
It's behaving correctly, when you do $sc->baz = 5;
it finds that set_baz method is there and executes this line $this->baz = $value;
and sets the value of baz property
Assume if the __get and __set working on in the class too then how you access $this->data in the class?
Upvotes: 0
Reputation: 239291
You're attempting to recursively call __set
, and PHP specifically disallows this.
__set
, you call set_baz
set_baz
, you do $this->baz = 5
__set
, except PHP prevents this from happening. If it didn't, your program would never end.You cannot trigger __set
if you're already within __set
. Instead, you are dynamically defining a new member variable called $this->baz
exactly as if __set
did not exist. If you var_dump
your object, you will find that it now contains both $data
and $baz
members.
Inside set_baz
, you need to explicitly write to $this->data
. You cannot write to $this->baz
.
Upvotes: 2