Назови случай, когда в Laravel нужно передавать параметры в конструктор

«Назови случай, когда в Laravel нужно передавать параметры в конструктор» — вопрос из категории Laravel, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В Laravel я передаю параметры в конструктор, когда зависимость не может быть автоматически разрешена контейнером из-за примитивного значения или необходимости конфигурации. Классический пример — сервис для работы с внешним API, которому нужен ключ и выбор стратегии.

<?php

namespace AppServicesPayment;

interface PaymentGateway
{
    public function charge(float $amount): bool;
}

class StripeGateway implements PaymentGateway
{
    private string $apiKey;
    private bool $useSandbox;

    // Контейнер не может сам "угадать" строку $apiKey и булевый $useSandbox
    public function __construct(string $apiKey, bool $useSandbox = false)
    {
        $this->apiKey = $apiKey;
        $this->useSandbox = $useSandbox;
    }

    public function charge(float $amount): bool
    {
        // Использование $this->apiKey и $this->useSandbox
        return true;
    }
}

// В сервис-провайдере явно указываем, как создать экземпляр
class AppServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->app->bind(PaymentGateway::class, function ($app) {
            return new StripeGateway(
                config('services.stripe.secret_key'), // Примитивный параметр
                config('app.env') === 'local'          // Условный параметр
            );
        });
    }
}

// Теперь в контроллере или другом классе зависимость внедрится автоматически
class PaymentController extends Controller
{
    public function __construct(private PaymentGateway $gateway) {}

    public function store(PaymentRequest $request)
    {
        $this->gateway->charge($request->amount);
    }
}

Такой подход также полезен для:

  • Тестирования: Можно легко подменить реализацию в тестах, передав мок.
  • Условного внедрения: Например, выбрать драйвер кэша (redis или file) на основе конфигурации.
  • Сложных зависимостей: Когда объект требует нескольких других сервисов и конфигурационных данных для инициализации.