首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >理解pimple php源代码

理解pimple php源代码
EN

Stack Overflow用户
提问于 2013-11-25 14:17:26
回答 1查看 624关注 0票数 3

Pimple是使用在silex框架中的php中的一个简单的依赖注入容器。我正在浏览源代码这里。在文档中,函数offsetGet返回附加到依赖容器的类的相同实例。offsetGet的相关代码是:

代码语言:javascript
复制
public function offsetGet($id)
{
    if (!isset($this->keys[$id])) {
        throw new InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));
    }

    if (
        isset($this->raw[$id])
        || !is_object($this->values[$id])
        || isset($this->protected[$this->values[$id]])
        || !method_exists($this->values[$id], '__invoke')
    ) {
        return $this->values[$id];
    }

    if (isset($this->factories[$this->values[$id]])) {
        return $this->values[$id]($this);
    }

    $this->frozen[$id] = true;
    $this->raw[$id] = $this->values[$id];

    return $this->values[$id] = $this->values[$id]($this);
 }

在这里,如果对象位于factories对象存储区(SplObjectStorage类型)中,它将返回一个带有id $id的类的新实例。然后,在最后一次返回中,再次将$this->values[$id]设置为对象的一个新实例,并返回该新实例。

return $this->values[$id] = $this->values[$id]($this)

这是我搞不懂的台词。对于同一offsetGet的不同调用,这行如何返回相同的实例。它不是每次都会返回一个新实例吗?请帮帮我。我试了很多次,但我不明白。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-12-11 09:35:14

我查看了pimple的源代码,发现一旦对象被实例化并保存在$this->values[$id]中,offsetGet的下一个调用将从第二个if条件返回。即这个if条件:

代码语言:javascript
复制
if (
    isset($this->raw[$id])
    || !is_object($this->values[$id])
    || isset($this->protected[$this->values[$id]])
    || !method_exists($this->values[$id], '__invoke')
) {
    return $this->values[$id];
}

查看单元测试,我发现没有神奇方法__invoke的对象可以共享。如果对象有一个神奇的方法__invoke(即可以将对象视为函数),则每次都会返回一个新实例。因此,您可以看到上述if语句上的第一个、第二个和第三个条件返回false。但是第四个条件返回true,因此$this->values[$id]每次都返回相同的实例。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20195343

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档