Информация может передаваться функциям через список аргументов, который представляет собой список выражений, разделенных запятыми. Аргументы оцениваются слева направо до фактического вызова функции ( нетерпеливое вычисление).

PHP поддерживает передачу аргументов по значению (по умолчанию), передачу по ссылке и значения аргументов по умолчанию . Также поддерживаются списки аргументов переменной длины и именованные аргументы .

 

Пример #1 Передача массивов в функции

<?php
function takes_array($input)
{
    echo "$input[0] + $input[1] = ", $input[0]+$input[1];
}
?>

Начиная с PHP 8.0.0, список аргументов функции может включать запятую в конце, которая будет игнорироваться. Это особенно полезно в тех случаях, когда список аргументов длинный или содержит длинные имена переменных, что делает удобным перечисление аргументов по вертикали.

Пример #2 Список аргументов функции с запятой в конце

<?php
function takes_many_args(
    $first_arg,
    $second_arg,
    $a_very_long_argument_name,
    $arg_with_default = 5,
    $again = 'a default string', // This trailing comma was not permitted before 8.0.0.
)
{
    // ...
}
?>

Передача аргументов по ссылке

По умолчанию аргументы функции передаются по значению (так что, если значение аргумента изменяется внутри функции, оно не изменяется вне функции). Чтобы разрешить функции изменять свои аргументы, они должны передаваться по ссылке.

Чтобы аргумент функции всегда передавался по ссылке, добавьте амперсанд (&) к имени аргумента в определении функции:

 

Пример #3 Передача параметров функции по ссылке

<?php
function add_some_extra(&$string)
{
    $string .= 'and something extra.';
}
$str = 'This is a string, ';
add_some_extra($str);
echo $str;    // outputs 'This is a string, and something extra.'
?>

Передача значения в качестве аргумента, который должен передаваться по ссылке, является ошибкой.

Значения аргументов по умолчанию

Функция может определять значения по умолчанию для аргументов, используя синтаксис, аналогичный назначению переменной. Значение по умолчанию используется только тогда, когда параметр не указан; в частности, обратите внимание, что передача nullне присваивает значение по умолчанию.

 

Пример #4 Использование параметров по умолчанию в функциях

<?php
function makecoffee($type = "cappuccino")
{
    return "Making a cup of $type.\n";
}
echo makecoffee();
echo makecoffee(null);
echo makecoffee("espresso");
?>

Приведенный выше пример выведет:

Приготовление чашки капучино.
Делаем чашку.
Приготовление чашки эспрессо.

Значения параметров по умолчанию могут быть скалярными значениями, массивами , специальным типом nullи, начиная с PHP 8.1.0, объектами, использующими новый синтаксис ClassName().

 

Пример #5 Использование нескалярных типов в качестве значений по умолчанию

<?php
function makecoffee($types = array("cappuccino"), $coffeeMaker = NULL)
{
    $device = is_null($coffeeMaker) ? "hands" : $coffeeMaker;
    return "Making a cup of ".join(", ", $types)." with $device.\n";
}
echo makecoffee();
echo makecoffee(array("cappuccino", "lavazza"), "teapot");
?>

 

Пример #6 Использование объектов в качестве значений по умолчанию (начиная с PHP 8.1.0)

<?php
class DefaultCoffeeMaker {
    public function brew() {
        return 'Making coffee.';
    }
}
class FancyCoffeeMaker {
    public function brew() {
        return 'Crafting a beautiful coffee just for you.';
    }
}
function makecoffee($coffeeMaker = new DefaultCoffeeMaker)
{
    return $coffeeMaker->brew();
}
echo makecoffee();
echo makecoffee(new FancyCoffeeMaker);
?>

Значение по умолчанию должно быть константным выражением, а не (например) переменной, членом класса или вызовом функции.

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

 

Пример #7 Неверное использование аргументов функции по умолчанию

<?php
function makeyogurt($container = "bowl", $flavour)
{
    return "Making a $container of $flavour yogurt.\n";
}
 
echo makeyogurt("raspberry"); // "raspberry" is $container, not $flavour
?>

Приведенный выше пример выведет:

Неустранимая ошибка: Uncaught ArgumentCountError: Слишком мало аргументов
 в функцию makeyogurt(), 1 передается в example.php в строке 42

А теперь сравните вышесказанное с этим:

 

Пример #8 Правильное использование аргументов функции по умолчанию

<?php
function makeyogurt($flavour, $container = "bowl")
{
    return "Making a $container of $flavour yogurt.\n";
}
 
echo makeyogurt("raspberry"); // "raspberry" is $flavour
?>

Приведенный выше пример выведет:

Делаем миску с малиновым йогуртом.

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

 

Пример #9 Правильное использование аргументов функции по умолчанию

<?php
function makeyogurt($container = "bowl", $flavour = "raspberry", $style = "Greek")
{
    return "Making a $container of $flavour $style yogurt.\n";
}

echo makeyogurt(style: "natural");
?>

Приведенный выше пример выведет:

Приготовление миски из малинового натурального йогурта.

Начиная с PHP 8.0.0, объявление обязательных аргументов после необязательных аргументов устарело . Как правило, это можно решить, отбросив значение по умолчанию, поскольку оно никогда не будет использоваться. Единственным исключением из этого правила являются аргументы формы Type $param = null, где по nullумолчанию тип неявно допускает значение NULL. Это использование остается разрешенным, хотя вместо этого рекомендуется использовать явный тип, допускающий значение NULL .

Пример #10 Объявление необязательных аргументов после обязательных аргументов

<?php
 function foo($a = [], $b) {} // Default not used; deprecated as of PHP 8.0.0
 function foo($a, $b) {}      // Functionally equivalent, no deprecation notice

 function bar(A $a = null, $b) {} // Still allowed; $a is required but nullable
 function bar(?A $a, $b) {}       // Recommended
 ?>

Примечание . Начиная с PHP 7.1.0, пропуск параметра, который не указывает значение по умолчанию, приводит к ошибке ArgumentCountError ; в предыдущих версиях выдавалось предупреждение.

Примечание . Аргументы, передаваемые по ссылке, могут иметь значение по умолчанию.

Списки аргументов переменной длины

PHP поддерживает списки аргументов переменной длины в пользовательских функциях с помощью ...токена.

Примечание . Также можно получить аргументы переменной длины, используя функции func_num_args() , func_get_arg() и func_get_args() . Этот метод не рекомендуется, поскольку он использовался до введения ...токена.

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

Пример #11 Использование ...для доступа к переменным аргументам

<?php
function sum(...$numbers) {
    $acc = 0;
    foreach ($numbers as $n) {
        $acc += $n;
    }
    return $acc;
}

echo sum(1, 2, 3, 4);
?>

Приведенный выше пример выведет: 10

...также может использоваться при вызове функций для распаковки массива , переменной Traversable или литерала в список аргументов:

Пример #12 Использование ...для предоставления аргументов

<?php
function add($a, $b) {
    return $a + $b;
}

echo add(...[1, 2])."\n";

$a = [1, 2];
echo add(...$a);
?>

Приведенный выше пример выведет: 3 3

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

Также можно добавить объявление типа перед ...токеном. Если это присутствует, то все захваченные аргументы ...должны соответствовать этому типу параметра.

Пример #13 Тип аргументов объявленной переменной

<?php
function total_intervals($unit, DateInterval ...$intervals) {
    $time = 0;
    foreach ($intervals as $interval) {
        $time += $interval->$unit;
    }
    return $time;
}

$a = new DateInterval('P1D');
$b = new DateInterval('P2D');
echo total_intervals('d', $a, $b).' days';

// This will fail, since null isn't a DateInterval object.
echo total_intervals('d', null);
?>

Приведенный выше пример выведет:

3 дня Уловимая фатальная ошибка: аргумент 2, переданный в total_intervals(), должен быть экземпляром DateInterval, заданным нулевым значением, вызванным в строке 14 и определенным в строке 2.

Наконец, переменные аргументы также могут быть переданы по ссылке с префиксом ...амперсанда ( &).

Старые версии PHP

Никакого специального синтаксиса не требуется, чтобы отметить, что функция является вариативной; однако для доступа к аргументам функции необходимо использовать функции func_num_args() , func_get_arg() и func_get_args() .

Первый приведенный выше пример будет реализован в старых версиях PHP следующим образом:

Пример #14 Доступ к переменным аргументам в старых версиях PHP

<?php
function sum() {
    $acc = 0;
    foreach (func_get_args() as $n) {
        $acc += $n;
    }
    return $acc;
}

echo sum(1, 2, 3, 4);
?>

Приведенный выше пример выведет: 10

Именованные аргументы

PHP 8.0.0 представил именованные аргументы как расширение существующих позиционных параметров. Именованные аргументы позволяют передавать аргументы функции на основе имени параметра, а не позиции параметра. Это делает значение аргумента самодокументируемым, делает аргументы независимыми от порядка и позволяет произвольно пропускать значения по умолчанию.

Именованные аргументы передаются путем префикса значения с именем параметра, за которым следует двоеточие. Допускается использование зарезервированных ключевых слов в качестве имен параметров. Имя параметра должно быть идентификатором, динамическое указание не допускается.

Пример #15 Синтаксис именованного аргумента

<?php
myFunction(paramName: $value);
array_foobar(array: $value);

// NOT supported.
function_name($variableStoringParamName: $value);
?>

Пример #16 Позиционные аргументы против именованных аргументов

<?php
// Using positional arguments:
array_fill(0, 100, 50);

// Using named arguments:
array_fill(start_index: 0, count: 100, value: 50);
?>

Порядок, в котором передаются именованные аргументы, не имеет значения.

Пример #17 Тот же пример, что и выше, но с другим порядком параметров

<?php
array_fill(value: 50, count: 100, start_index: 0);
?>

Именованные аргументы можно комбинировать с позиционными аргументами. В этом случае именованные аргументы должны идти после позиционных аргументов. Также можно указать только некоторые из необязательных аргументов функции, независимо от их порядка.

Пример #18 Объединение именованных аргументов с позиционными аргументами

<?php
htmlspecialchars($string, double_encode: false);
// Same as
htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, 'UTF-8', false);
?>

Передача одного и того же параметра несколько раз приводит к исключению Error.

Пример #19 Ошибка при многократной передаче одного и того же параметра

<?php
function foo($param) { ... }

foo(param: 1, param: 2);
// Error: Named parameter $param overwrites previous argument
foo(1, param: 2);
// Error: Named parameter $param overwrites previous argument
?>

Начиная с PHP 8.1.0, можно использовать именованные аргументы после распаковки аргументов. Именованный аргумент не должен переопределять уже распакованные аргументы.

Пример #20 Использование именованных аргументов после распаковки

<?php
function foo($a, $b, $c = 3, $d = 4) {
  return $a + $b + $c + $d;
}

var_dump(foo(...[1, 2], d: 40)); // 46
var_dump(foo(...['b' => 2, 'a' => 1], d: 40)); // 46

var_dump(foo(...[1, 2], b: 20)); // Fatal error. Named parameter $b overwrites previous argument
?>