Obiecte leneșe (newLazyGhost, newLazyProxy) în PHP

Creează un obiect a cărui inițializare (de exemplu citirea din baza de date) rulează abia la prima folosire.

Sintaxă
ReflectionClass::newLazyGhost(callable $initializer, int $options = 0): object
ReflectionClass::newLazyProxy(callable $factory, int $options = 0): object

Ce face Obiecte leneșe (newLazyGhost, newLazyProxy)

Un obiect leneș (lazy object) arată și se comportă ca un obiect normal al clasei, dar codul care îl pregătește rulează abia când citești sau scrii prima dată o proprietate. Dacă obiectul nu este folosit deloc, inițializarea nu rulează niciodată.

newLazyGhost creează direct obiectul clasei și apelează funcția ta cu el ca parametru, ca să îl completezi (de obicei apelând constructorul). newLazyProxy primește o funcție care returnează un obiect real; proxy-ul trimite apoi toate accesările spre acel obiect.

Funcția este folosită mai ales de containere de dependențe și ORM-uri (Symfony, Doctrine), ca să nu construiască servicii scumpe care nu sunt folosite în cererea curentă.

Parametri

Parametru Descriere
$initializer Pentru ghost: function (object $obiect): void, completează obiectul primit.
$factory Pentru proxy: function (object $proxy): object, returnează obiectul real.
$options Opțional. De exemplu ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE.

Ce returnează

Un obiect neinițializat al clasei; se inițializează singur la prima folosire.

Exemple

Exemplul 1: Ghost: constructorul rulează la prima citire

<?php
class Raport
{
    public array $randuri;

    public function __construct(public string $luna)
    {
        echo "Se încarcă raportul pentru $luna...\n";
        $this->randuri = ["Iași: 1200 lei", "Cluj: 950 lei"];
    }
}

$clasa = new ReflectionClass(Raport::class);
$raport = $clasa->newLazyGhost(function (Raport $r) {
    $r->__construct("octombrie");
});

echo "Obiect creat\n";
var_dump($clasa->isUninitializedLazyObject($raport));

echo $raport->randuri[0] . "\n";
var_dump($clasa->isUninitializedLazyObject($raport));

Rezultat

Obiect creat
bool(true)
Se încarcă raportul pentru octombrie...
Iași: 1200 lei
bool(false)

Exemplul 2: Proxy: obiectul real vine dintr-o funcție

<?php
class Conexiune
{
    public function __construct(public string $gazda)
    {
        echo "Conectare la $gazda\n";
    }
}

$clasa = new ReflectionClass(Conexiune::class);
$conexiune = $clasa->newLazyProxy(fn() => new Conexiune("db.exemplu.ro"));

echo "Aplicația a pornit\n";
echo $conexiune->gazda;

Rezultat

Aplicația a pornit
Conectare la db.exemplu.ro
db.exemplu.ro

Greșeli frecvente

  • Te aștepți ca var_dump() să inițializeze obiectul. var_dump și get_class nu declanșează inițializarea; accesarea unei proprietăți o declanșează.
  • Încerci să creezi un obiect leneș dintr-o clasă internă PHP, de exemplu ArrayObject: PHP aruncă o eroare, pentru că mecanismul merge doar pentru clasele scrise de tine (sau care moștenesc doar stdClass).

Comenzi înrudite

  • Property hooks (get / set): Cod care rulează automat când o proprietate este citită (get) sau modificată (set), fără metode getter și setter separate.
  • __construct: Constructorul este metoda rulată automat la new. Pregătește obiectul cu datele de pornire.
  • new (și new fără paranteze în PHP 8.4): Creează un obiect nou dintr-o clasă. Din PHP 8.4 poți apela o metodă direct pe new Clasa(), fără paranteze în plus.