Довгий список параметрів - code smell: виклик важко читати, легко переплутати порядок аргументів однакового типу, а кожна зміна сигнатури зачіпає всі місця виклику.
$this->createInvoice($customerId, $amount, 'UAH', $dueDate, true, false, null, 'uk');
// що означають true, false і null?
Варіанти лікування:
1. Об'єкт параметрів (Introduce Parameter Object) - параметри, що завжди йдуть разом, об'єднуються в клас:
final readonly class InvoiceData
{
public function __construct(
public int $customerId,
public Money $amount,
public DateTimeImmutable $dueDate,
public bool $sendByEmail = true,
public bool $isDraft = false,
public ?string $note = null,
public string $locale = 'uk',
) {}
}
$this->createInvoice(new InvoiceData(
customerId: $customer->id,
amount: Money::uah(125050),
dueDate: now()->addDays(14)->toImmutable(),
));
Іменовані аргументи PHP 8 роблять створення читабельним, значення за замовчуванням прибирають шум, а readonly гарантує незмінність. Часто в такий об'єкт перетікає й логіка (валідація, обчислення), - він стає об'єктом-значенням, а не просто контейнером.
2. Іменовані аргументи без нового класу - для рідкісних викликів з кількома необов'язковими параметрами:
$this->createInvoice($customerId, $amount, dueDate: $date, isDraft: true);
3. Передавати весь об'єкт замість його частин (Preserve Whole Object): calculateShipping($order) замість calculateShipping($order->weight, $order->country, $order->city, $order->express).
4. Прибрати булеві прапорці (Remove Flag Argument): createInvoice(..., isDraft: true) часто означає два різні методи - createDraftInvoice() і issueInvoice().
5. Перенести параметри в конструктор: залежності (сервіси, конфігурація), що передаються в кожен виклик, - у конструктор класу через впровадження залежностей.
Ознака, що проблема глибша: метод приймає багато параметрів, бо робить забагато. Тоді спершу розділити метод (Extract Method/Class), а вже потім дивитися на параметри.
У Laravel-проєктах такі об'єкти часто будують з Form Request ($request->toDto()) чи використовують spatie/laravel-data, що поєднує DTO з валідацією й перетворенням з/у масив.
Докладніше в документації: Каталог рефакторингів: Introduce Parameter Object