Зарегистрируйтесь, чтобы продолжить обучение

Упаковка аргументов PHP: Функции

Сигнатура функции array_merge в документации определяется так:

array_merge(array ...$arrays): array

Она указывает, что в array_merge можно передать любое количество массивов:

<?php

array_merge();
# Array
# (
# )

array_merge([1]);
# Array
# (
#     [0] => 1
# )
array_merge([1], [1]);
# Array
# (
#     [0] => 1
#     [1] => 1
# )
array_merge([1], [1], [3, 4]);
# Array
# (
#     [0] => 1
#     [1] => 1
#     [2] => 3
#     [3] => 4
# )
array_merge([1], [1], [3, 4], []);
# Array
# (
#     [0] => 1
#     [1] => 1
#     [2] => 3
#     [3] => 4
# )

С точки зрения вызова, в этом нет ничего необычного — просто разное число аргументов. А вот определение функции с переменным числом аргументов выглядит необычно, потому что здесь незнакомый для нас синтаксис:

<?php

function sum(...$numbers)
{
    return array_sum($numbers);
}

echo sum(9, 4); // => 13
echo sum(-3, 0, 3, 1); // => 1

Три точки представляют собой оператор Spread. Основная сложность в том, что оператор Spread выполняет разные действия в зависимости от того, где он применяется. В определении функции он выполняет упаковку параметров, а при вызове — распаковку. Об упаковке мы поговорим в этом уроке, а о распаковке — в следующем.

Итак, оператор Spread в определении функции собирает все переданные аргументы в массив. Если в функцию не передается ни одного аргумента, то массив будет пустым:

<?php

echo sum(); // => 0

Обратите внимание, что этому оператору не важен тип аргументов. Они все станут элементами массива, даже если мы передаем на вход функции массивы:

<?php

function show(...$arguments)
{
    print_r($arguments);
}

show([]);
# Array
# (
#     [0] => Array
#         (
#         )
#
# )

show([1, 3], [], 3);
#  Array
# (
#     [0] => Array
#         (
#             [0] => 1
#             [1] => 3
#         )
#
#     [1] => Array
#         (
#         )
#
#     [2] => 3
# )

Теперь взглянем на сигнатуру функции min(), которая ищет наименьшее значение:

min(mixed $value, mixed ...$values): mixed

Видно, что функция min() ждет на вход как минимум одно значение, опциональны только следующие. Такого поведения можно добиться следующим кодом:

<?php

function sum($a, ...$numbers)
{
    return $a + array_sum($numbers);
}

echo sum();
// PHP Fatal error:  Uncaught ArgumentCountError: Too few arguments to function sum(), 0 passed

echo sum(10); // => 10
echo sum(10, 4); // => 14
echo sum(8, 10, 4); // => 22

То же самое можно сделать и для двух аргументов:

<?php

function sum($a, $b, ...$numbers)
{
    # ...
}

Эту идею можно продолжать и дальше, делая обязательными нужное количество аргументов. Единственное ограничение — оператор Spread можно использовать только для последнего аргумента. Другими словами, такой код синтаксически неверен:

<?php

function sum(...$numbers, $a)
{
    # ...
}

Такой код тоже не верен с точки зрения синтаксиса:

<?php

function sum($a, ...$numbers, $a)
{
    # ...
}

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы
профессия
от 25 000 ₸ в месяц
Разработка веб-приложений на Laravel
10 месяцев
с нуля
Старт 26 декабря

Используйте Хекслет по-максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»