Za pomocą wcześniej poznanej refleksji tworzymy graf zależności – mechanizm naprawdę potężny. Co tu gadać – do dzieła!

Oto nasza klasa bez konstruktora Person:

class Person {
    public string $name;
    public int $age;
}

A oto klasa couple, której konstruktor wymaga 2 obiektów:

class Couple {
    public function __construct(public Person $person1, public Person $person2)
    {
        
    }
}

Fakt, że typami wymaganymi są obiekty a nie scalary sprawia, że raz napisany mechanizm tworzenia obiektów będzie można zastosować rekurencyjnie.

Nie uprzedzając faktów:

class ReflectionHelper {
    public static function getObject(string $class_name): object
    {
        $reflector = new ReflectionClass($class_name);

        $constructor = $reflector->getConstructor();

        $dependencies = [];

        if ($constructor === null) {

            return new $class_name;

        }

        //(...)
    }
}

To chyba rozumiemy – jak nie ma konstuktora, tworzymy obiekt bez konstruktora.

Teraz musimy obsłużyć mechanizm zależności:

class ReflectionHelper {
    public static function getObject(string $class_name): object
    {
        $reflector = new ReflectionClass($class_name);

        $constructor = $reflector->getConstructor();

        $dependencies = [];

        if ($constructor === null) {

            return new $class_name;

        }

        foreach ($constructor->getParameters() as $parameter) {

            $type = (string) $parameter->getType();

            $dependencies[] = static::getObject($type);

        }

        return new $class_name(...$dependencies);
    }
}

Mamy tutaj wywołanie rekurencyjne getObject i w ten sposób zbieramy zależności – zakładając, że konstuktory mają tylko obiekty.

Sprawdźmy, jak to działa:

$couple1 = ReflectionHelper::getObject(Couple::class);
print_r($couple1);
//Couple Object ( [person1] => Person Object ( ) [person2] => Person Object ( ) )

Już teraz widzimy, jak potężny jest to mechanizm.