Here's a puzzler: __set($value, $name) not called when a setter matching $obj->$key exists, but is called when it doesn't
Here's the context:
$values = $form->getValues();
foreach($values as $key=>$value) {
$obj->{$key} = $value;
}
If $key
is a valid key, __set($name, $value)
is not called. If $key
is not a valid key, it is. Here's what my set looks like:
public function __set($name, $value) {
$method = 'set' . ucfirst($name);
if(method_exists($method)) {
$this->$method($value);
} else {
throw new RuntimeException('Attempt to access a non-existant property with method ' . $method);
}
}
In the object to which the __set($name, $value)
method belongs, all properties are private and underscored. So for key 'name' there would be the following:
private $_name;
public function setName($name) {
$this->_name = $n开发者_运维问答ame;
return $this;
}
I know that it isn't called because I tried inserting an exception just after the $method = 'set' . ucfirst($name);
. That exception was hit when $name
did not reference a valid setter, but was not hit when it didn't. It should have been hit every time. Anyone have any clue what's happening here?
This is by design. From the manual
__set() is run when writing data to inaccessible properties.
If you have public
properties matching $key
, they will be set because they are accessible.
Also, your use of method_exists()
is incorrect. It should be
if (method_exists($this, $method))
That's documented behavior; it's how __set() actually works: documentation here.
精彩评论