Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама
Senior PHP 8+

Що таке ліниві об'єкти (lazy objects) у PHP 8.4 і де вони корисні?

Лінивий об'єкт створюється одразу, але його справжня ініціалізація (дорогий конструктор, запит до бази, з'єднання) відкладається до моменту, коли об'єкт справді знадобиться. PHP 8.4 зробив це вбудованою можливістю мови через Reflection.

Два види:

  • Ghost - сам об'єкт потрібного класу, який ініціалізується «на місці» при першому зверненні до його стану:
$reflector = new ReflectionClass(Connection::class);

$connection = $reflector->newLazyGhost(function (Connection $object): void {
    $object->__construct(config('database.dsn'));   // підключення лише тепер
});

// ... з'єднання ще не встановлено
$connection->query('SELECT 1');   // перше звернення до властивостей - ініціалізація
  • Proxy - об'єкт-замісник, який при першому зверненні створює справжній екземпляр через фабрику й далі перенаправляє йому всі звернення:
$service = $reflector->newLazyProxy(fn () => $container->make(HeavyService::class));

Важливий нюанс: ініціалізацію запускає звернення до властивостей об'єкта. Виклик методу, який не чіпає стан, лінивий об'єкт не ініціалізує.

Де це корисно:

  • Контейнери залежностей: сервіс, впроваджений у контролер, але не використаний у цьому запиті, не створюється взагалі.
  • ORM: зв'язана сутність завантажується з бази лише при зверненні до неї (так Doctrine давно робила через згенеровані класи-проксі - тепер це вміє мова).
  • Важкі клієнти: з'єднання з Redis, S3, сторонніми API, яке потрібне лише в частині запитів.

Чим краще за рукописні проксі: не треба генерувати код класів-проксі, об'єкт лишається того самого класу (працюють instanceof і типи), а final-класи теж можна зробити лінивими.

Обмеження: ініціалізація може відбутися в несподіваний момент (наприклад, при var_dump чи серіалізації), а помилка в ініціалізаторі виникне там, де об'єкт уперше використали, а не там, де його створили.

Докладніше в документації: Ліниві об'єкти

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання