Понимание исходного кода 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] возвращает один и тот же экземпляр каждый раз.

Другие вопросы по тегам