这是一个谜题:当存在与 $obj->$key 匹配的 setter 时,__set($value, $name) 不会被调用,但在不存在时会被调用

发布于 2024-12-09 12:21:46 字数 942 浏览 0 评论 0原文

上下文如下:

$values = $form->getValues();
foreach($values as $key=>$value) {         
$obj->{$key} = $value;
}

如果 $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);
    }
}

__set($name, $value) 方法所属的对象中,所有属性都是私有的并带有下划线。因此,对于键“name”,会有以下内容:

private $_name;

public function setName($name) {
    $this->_name = $name; 
    return $this; 
}

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

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 = $name; 
    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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

拍不死你 2024-12-16 12:21:46

这是设计使然。来自手册

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

如果您有与 $key 匹配的 public 属性,则会设置它们,因为它们可访问

另外,您使用 method_exists()是不正确的。应该是

if (method_exists($this, $method))

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))
蒗幽 2024-12-16 12:21:46

这是有记录的行为;这就是 __set() 的实际工作原理: 文档在这里

That's documented behavior; it's how __set() actually works: documentation here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文