gpt4 book ai didi

php - 理解疙瘩php源码

转载 作者:搜寻专家 更新时间:2023-10-31 20:41:54 25 4
gpt4 key购买 nike

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

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 Object Store(SplObjectStorage 类型)中,它返回一个id为$id的类的新实例。然后在最后一次返回中再次将 $this->values[$id] 设置为该对象的一个​​新实例并返回该新实例。

返回 $this->values[$id] = $this->values[$id]($this)

这是我无法理解的行。对于同一 $id 的 offsetGet 的不同调用,这一行应该如何返回相同的实例。它不会每次都返回一个新实例吗?请帮我。我尝试了很多,但我不明白。

最佳答案

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

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] 每次都返回相同的实例。

关于php - 理解疙瘩php源码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20195343/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com