getter setter - PHP magic methods behave differently when dynamically building property names -
i have 2 examples of simple class using __set() , __get() magic methods. 1 throws fatal error , other not when attempting access protected property unset() function.
in example 1, i'm naming protected property starting underscore , allowing access via friendly name , prepending underscore in __set() , __get() methods. (effectively exposing property without underscore).
in example 2, i'm not starting name underscore , allowing access via name directly in __set() , __get() methods.
questions
1) why example 1 not throw fatal error while example 2 does throw fatal error? expect either both throw error or neither throw error.
2) also, why example 1 not unset property? expect property not contain value after unset() function called.
example 1
class example { protected $_my_property; function __get($name) { echo '<h4>__get() triggered!</h4>'; $name = '_' . $name; if (property_exists($this, $name)) { return $this->$name; } else { trigger_error("undefined property in __get(): $name"); return null; } } function __set($name, $value) { echo '<h4>__set() triggered!</h4>'; $name = '_' . $name; if (property_exists($this, $name)) { $this->$name = $value; return; } else { trigger_error("undefined property in __set(): {$name}"); } } } $myexample = new example(); $myexample->my_property = 'my_property has value'; echo $myexample->my_property; unset($myexample->my_property); echo "did unset property?: {$myexample->my_property}"; example 2
class example { protected $my_property; function __get($name) { echo '<h4>__get() triggered!</h4>'; if (property_exists($this, $name)) { return $this->$name; } else { trigger_error("undefined property in __get(): $name"); return null; } } function __set($name, $value) { echo '<h4>__set() triggered!</h4>'; if (property_exists($this, $name)) { $this->$name = $value; return; } else { trigger_error("undefined property in __set(): {$name}"); } } } $myexample = new example(); $myexample->my_property = 'my_property has value'; echo $myexample->my_property; unset($myexample->my_property); echo "did unset property?: {$myexample->my_property}"; as side note, simplistic example demonstrates behavior i'm seeing in real world project. thanks!
the problem have have not defined __unset() magic method.
this means when call unset($myexample->my_property), trying directly unset public property specified name.
in example 1, real protected property has underscore in it's name. therefore, when try unset property, php looks @ object, sees there nothing specified name, , ignores it.
this same behaviour unset() exhibit if tried unset non-existent variable or array element.
however in example 2, protected property has same name have given in unset() call.
in example, php looks @ object , sees property exist it non-accessible. therefore throws error complaining can't unset property.
you can resolve issue including __unset() method alongside __get() , __set() methods. if you're planning use magic methods, should ideally define three.
hope helps.
Comments
Post a Comment