Ответ
В PHP есть несколько способов создать экземпляр одного класса внутри другого. Выбор зависит от степени связанности классов и требований к тестируемости.
1. Создание в конструкторе (Жёсткая зависимость)
Самый простой, но наименее гибкий способ. Класс A жёстко зависит от конкретной реализации B.
class B {
public function doSomething(): string {
return "Work done by B";
}
}
class A {
private B $b;
public function __construct() {
// Класс A сам создаёт экземпляр B
$this->b = new B();
}
public function run(): void {
echo $this->b->doSomething();
}
}
// Использование
$a = new A(); // Внутри автоматически создастся B
$a->run(); // Output: Work done by B
2. Внедрение зависимости через конструктор (Dependency Injection - DI)
Предпочтительный способ. Класс A получает уже готовый объект B извне. Это делает код гибким и легко тестируемым (можно подменить B на mock-объект в тестах).
class A {
private B $b;
// B "внедряется" в A извне
public function __construct(B $b) {
$this->b = $b;
}
public function run(): void {
echo $this->b->doSomething();
}
}
// Использование
$b = new B();
$a = new A($b); // Передаём экземпляр B в A
$a->run();
// В Laravel или другом DI-контейнере это происходит автоматически:
// $a = app(A::class); // Контейнер сам создаст B и передаст его в A
3. Ленивая инициализация (Lazy Initialization)
Объект B создаётся только в момент первого обращения к нему, а не при создании A. Полезно, если создание B — ресурсоёмкая операция, которая может не понадобиться.
class A {
private ?B $b = null; // Инициализируем как null
public function getB(): B {
if ($this->b === null) {
$this->b = new B(); // Создаём только здесь
}
return $this->b;
}
}
// Использование
$a = new A(); // Класс B ещё не создан
// ... какая-то другая работа ...
$a->getB()->doSomething(); // Класс B создаётся в этот момент
Итог: Для чистого, тестируемого кода я почти всегда выбираю внедрение зависимости (вариант 2). Фреймворки вроде Laravel или Symfony имеют мощные DI-контейнеры, которые полностью берут на себя управление созданием и связыванием таких объектов.