Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як передати аргумент за посиланням і чому це часто погана ідея?

За замовчуванням аргументи передаються за значенням: функція отримує копію, і зміна параметра не впливає на змінну викликача. Знак & у сигнатурі робить передачу за посиланням:

function addItem(array &$cart, string $item): void
{
    $cart[] = $item;
}

$cart = [];
addItem($cart, 'книга');
// $cart === ['книга']

Де це в стандартній бібліотеці: sort(), array_push(), preg_match() (масив збігів), array_walk() - вони змінюють передану змінну.

Чому у власному коді це часто погана ідея:

  • Прихований побічний ефект. З виклику addItem($cart, 'книга') не видно, що $cart зміниться. Читач має знати сигнатуру.
  • Важче міркувати й тестувати: функція не просто повертає результат, а змінює стан ззовні.
  • Не дає економії пам'яті. Масиви копіюються ліниво (copy-on-write), тож передача за значенням не копіює дані, доки їх не змінять.
  • Не можна передати вираз: addItem([], 'x') чи addItem(getCart(), 'x') - помилка, потрібна саме змінна.

Краща альтернатива - повертати нове значення:

function withItem(array $cart, string $item): array
{
    return [...$cart, $item];
}

$cart = withItem($cart, 'книга');

Або - об'єкт зі станом і методом: $cart->add('книга') - зміна очевидна з виклику.

Об'єкти й так не копіюються: функція, що отримала об'єкт, працює з тим самим об'єктом. & для об'єкта потрібен лише тоді, коли функція має замінити змінну іншим об'єктом.

Коли посилання виправдані: зміна великих вкладених структур на місці в гарячому коді та рідкісні API на кшталт «повернути кілька значень» - хоча тут читабельніше повернути масив чи об'єкт.

Докладніше в документації: Передача аргументів за посиланням

Схожі питання