Понимание исходного кода PHP прыщ
Pimple - это простой контейнер для внедрения зависимостей в php, используемый в silex framework. Я шел через исходный код здесь. В документации функция 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
Магазин объектов (SplObjectStorage
тип), он возвращает новый экземпляр класса с идентификатором $id. затем в последнем возвращении снова $this->values[$id]
устанавливается на новый экземпляр объекта, и этот новый экземпляр возвращается.
return $this->values[$id] = $this->values[$id]($this)
,
Это строка, которую я не понимаю. Как эта строка должна возвращать один и тот же экземпляр для разных вызовов offsetGet
за тот же $id. Не будет ли каждый раз возвращать новый экземпляр? Пожалуйста, помогите мне. Я много пробовал, но не понимаю.
1 ответ
Я посмотрел на исходный код прыща и обнаружил, что как только объект создается и хранится в $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. но четвертое условие возвращает истину и, следовательно, $this->values[$id]
возвращает один и тот же экземпляр каждый раз.