这是一个益智游戏:__set($ value,$ name)当匹配$ obj - > $ key的setter存在时未调用,但是当它不存在时调用

Dan*_*ham 1 php magic-methods

这是上下文:

$values = $form->getValues();
foreach($values as $key=>$value) {         
$obj->{$key} = $value;
}
Run Code Online (Sandbox Code Playgroud)

如果$key是有效密钥,__set($name, $value)则不会被调用.如果$key不是有效密钥,则为.这是我的集合的样子:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

在该__set($name, $value)方法所属的对象中,所有属性都是私有的并且是下划线的.因此对于关键'名称',将有以下内容:

private $_name;

public function setName($name) {
    $this->_name = $name; 
    return $this; 
}
Run Code Online (Sandbox Code Playgroud)

我知道它没有被调用,因为我尝试在之后插入一个异常$method = 'set' . ucfirst($name);.当$name没有引用有效的setter时会触发该异常,但是当它没有引用时就没有被触发.它应该每次都被击中.任何人都知道这里发生了什么?

Phi*_*hil 7

这是设计的.从手册

将数据写入不可访问的属性时运行__set().

如果您具有public匹配的属性$key,则将设置它们,因为它们是可访问的.

此外,您的使用method_exists()是不正确的.它应该是

if (method_exists($this, $method))
Run Code Online (Sandbox Code Playgroud)