开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜