Параметры и именованные аргументы
Чему вы научитесь:
- задавать параметрам значения по умолчанию и передавать аргументы по имени;
- объявлять типы параметров и результата и объяснять, что меняет
declare(strict_types=1); - предсказывать, изменит ли функция переданную ей переменную и какие переменные она видит;
- писать функцию, которая вызывает саму себя, и вовремя её останавливать.

Как вы уже знаете, функция получает аргументы, выполняет своё тело и возвращает результат через return. В этой теме мы разберём функции подробнее, и через всю тему пройдёт одна картинка — автомат с кофе.
Вы бросаете в автомат монеты и нажимаете кнопки — это аргументы. Автомат готовит напиток и выдаёт его в лоток — это результат return. У некоторых кнопок есть настройка на случай, если их не трогать: если не нажать кнопку сахара, автомат положит одну ложку.
У функции так же: параметру можно заранее задать значение, которое PHP подставит, если аргумента нет. Вот функция, которая описывает заказ:
<?php
function coffee($size, $sugar = 1, $milk = false)
{
return $size . ' ml, sugar ' . $sugar . ($milk ? ', milk' : '');
}
echo coffee(200), "\n"; // 200 ml, sugar 1
echo coffee(300, 0), "\n"; // 300 ml, sugar 0
echo coffee(300, 2, true), "\n"; // 300 ml, sugar 2, milkДавайте разберём вызовы по шагам:
coffee(200)передаёт один аргумент. Он попадает в$size, а$sugarи$milkполучают заданные заранее1иfalse.coffee(300, 0)передаёт два аргумента:300попадает в$size, а0— в$sugar.coffee(300, 2, true)заполняет все три параметра, и в заказе появляется молоко.
Такие аргументы называют позиционными: они заполняют параметры по порядку, слева направо. Первый аргумент попадает в первый параметр, второй — во второй.
Значения по умолчанию
Запись $sugar = 1 в объявлении функции задаёт значение по умолчанию: PHP подставит 1, если вызов не передал этот аргумент. Параметр без такой записи, как $size, обязателен.
У таких параметров три правила:
- параметры со значением по умолчанию ставят после обязательных;
- если поставить такой параметр перед обязательным, PHP выдаст
Deprecatedи всё равно будет считать его обязательным; - обязательный параметр пропускать нельзя.
Вот что будет, если вызвать coffee совсем без аргументов:
echo coffee(), "\n"; // ✗Fatal error: Uncaught ArgumentCountError: Too few arguments to function coffee(), 0 passed and at least 1 expectedЭто ошибка, а не предупреждение: программа останавливается на этой строке. В сообщении сказано, что передано 0 аргументов, а нужен хотя бы 1 — значение для $size.
Здесь автомат и функция расходятся. Автомат без монеты молча ждёт, а функция без обязательного аргумента останавливает всю программу.
Именованные аргументы
Допустим, нужен кофе с молоком и обычной ложкой сахара. Позиционно придётся повторить сахар: coffee(300, 1, true). Чтобы пропустить середину, в PHP 8 есть именованные аргументы: перед значением пишут имя параметра без $ и двоеточие.
echo coffee(300, milk: true), "\n"; // 300 ml, sugar 1, milk
echo coffee(milk: true, size: 250), "\n"; // 250 ml, sugar 1, milkРазберём по шагам:
- В первом вызове
300попадает в$sizeпо позиции, аmilk: true— в$milkпо имени. $sugarпропущен, поэтому получает значение по умолчанию1.- Во втором вызове названы оба аргумента, и их порядок уже не важен:
size: 250попадёт в$size, где бы он ни стоял.
Правила для именованных аргументов:
- позиционные аргументы идут первыми, именованные — после них;
- имя параметра пишут без знака
$:milk: true; - нельзя задать по имени параметр, который уже получил значение от позиционного аргумента: на
coffee(300, size: 200)PHP ответитError: Named parameter $size overwrites previous argument; - имя должно совпадать с именем параметра: на
coffee(300, mlk: true)PHP ответитError: Unknown named parameter $mlk.
Именованные аргументы ещё и подписывают значения. Сравните coffee(300, 1, true) и coffee(300, milk: true): во втором вызове сразу видно, что значит true.
На собеседовании спрашивают, что меняют именованные аргументы. Ответ: аргумент находит параметр по имени, а не по позиции, поэтому необязательные параметры можно пропускать. У этого есть цена: имя параметра становится частью договора функции, и после переименования $milk вызовы с milk: true сломаются.
return завершает вызов
return не только отдаёт значение, но и сразу завершает вызов. Если return стоит внутри if и условие истинно, строки функции ниже уже не выполнятся.
Как вы уже знаете, функция без return тоже завершается, когда доходит до закрывающей скобки, и возвращает null.
Частая ошибка
Позиционный аргумент поставили после именованного:
echo coffee(milk: true, 300), "\n"; // ✗Fatal error: Cannot use positional argument after named argumentPHP проверяет порядок аргументов ещё до запуска, так же как синтаксис. Поэтому файл не выполняется вовсе: не напечатаются даже строки выше этой. Исправление — сначала позиционные аргументы, потом именованные: coffee(300, milk: true).
Главное
- Параметр со значением по умолчанию можно не передавать; такие параметры ставят после обязательных.
- Без обязательного аргумента вызов останавливает программу ошибкой
ArgumentCountError. - Именованный аргумент
milk: trueнаходит параметр по имени, поэтому необязательные параметры перед ним можно пропустить. - Позиционные аргументы идут первыми, а
returnсразу завершает вызов.