Разработчику. Сборник рецептов PHP
Задавайте вопросы

Создание функции, принимающей
переменное количество аргументов

Вернуться назад

Задача

Необходимо определить функцию, принимающую переменное количество аргументов.

Решение

Передайте массив и поместите в него переменные аргументы:

// определение среднего группы чисел
function mean($numbers) {
     // инициализируем, чтобы избежать предупреждений
     $sum = 0;

     // количество элементов в массиве
     $size = count($numbers);

     // выполняем цикл по массиву и суммируем числа
     for ($i = 0; $i < $size; $i++) {
     $sum += $numbers[$i];

     }

     // делим на количество чисел
     $average = $sum / $size;

     // возвращаем среднее
     return $average;

}

$mean = mean(array(96 , 93 , 97));

Обсуждение

Есть два хороших решения, зависящих от стиля программирования и предпочтений программиста. Более традиционным для PHP является метод, описанный выше в разделе «Решение». Мы предпочитаем именно его, т. к. применение массивов в PHP – обычное дело, и все программисты хорошо знакомы с массивами и их поведением.

Таким образом, хотя этот метод требует некоторых дополнительных накладных расходов, группирование переменных общепринято. Оно применяется в примере "Именованные параметры" для создания именованных параметров и в примере "Возвращение более одного значения" для возвращения из функции более одного значения. Кроме того, внутри функции синтаксис доступа и манипуляции элементами массива включает такие основные команды, как $array[$i] и count($array).

Однако выглядеть это может неуклюже, поэтому PHP обеспечивает альтернативу и разрешает прямой доступ к списку аргументов:

// определение среднего группы чисел
function mean() {
     // инициализируем, чтобы избежать предупреждений
     $sum = 0;

     // количество аргументов, переданных в функцию
     $size = func_num_args();

     // выполняем цикл по аргументам и суммируем числа
     for ($i = 0; $i < $size; $i++) {
     $sum += func_get_arg($i);

          }

     // делим на количество чисел
     $average = $sum / $size;
     // возвращаем среднее

     return $average;

}

$mean = mean(96 , 93 , 97);

В этом примере задействован ряд функций, возвращающих данные, основанные на аргументах, переданных функции, из которой они вызываются. Сначала функция func_num_args() возвращает целое число, показывающее количество аргументов, переданных в вызывающую ее функцию; в данном случае это функция mean(). Затем отсюда можно вызвать функцию func_get_arg(), чтобы определить конкретное значение аргумента для каждой позиции.

При вызове функции mean(96, 93, 97) функция func_num_args() возвращает 3. Первый аргумент находится в позиции 0, поэтому цикл выполняется от 0 до 2, а не от 1 до 3. То есть это происходит в цикле for, когда переменная $i пробегает значения от 0 до числа, меньшего $size. Как можно видеть, это та же самая логика, что была реализована в первом примере, в котором был передан массив. Можно не беспокоиться о возможных накладных расходах от вызова функции func_get_arg() внутри цикла. Эта версия в действительности быстрее метода передачи массива.

Ниже приведена третья версия этой функции, в которой функция func_num_args() возвращает массив, содержащий все значения, переданные функции. Ее завершение выглядит как гибрид двух предыдущих функций:

// определение среднего группы чисел
function mean() {
     // инициализируем, чтобы избежать предупреждений
     $sum = 0;

     // загружаем аргументы в массив $numbers
     $numbers = func_get_args();

     // количество элементов в массиве
     $size = count($numbers);

     // выполняем цикл по массиву и суммируем числа
     for ($i = 0; $i < $size; $i++) {
          $sum += $numbers[$i];

          }

     // делим на количество чисел
     $average = $sum / $size;

     // возвращаем среднее
     return $average;

}

$mean = mean(96, 93, 97);

Здесь мы получаем двойную выгоду от того, что нет необходимости помещать числа во временный массив для передачи их в функцию mean(), но внутри функции можно трактовать их так, как будто это сделано. К сожалению, этот способ несколько медленнее первых двух.

См. также

Документацию по функции func_num_arg() на http://www.php.net/func-num-arg, по функции func_get_arg() на http://www.php.net/func-get-arg и по функции func_get_args() на http://www.php.net/func-get-args.

Вернуться назад

Рейтинг@Mail.ru

Яндекс.Метрика

Индекс цитирования


Рейтинг Сайтов ДОСКИ.РУ