Parameters and Arguments

Parameters are the inputs a function declares; arguments are the values you pass when you call it. PHP gives you default values, named arguments, variadic parameters and passing by reference — enough flexibility to make function calls both short and self-explanatory.

Default values

A parameter with a default value is optional. Optional parameters should come after the required ones:

PHP
<?php

function greet(string $name, string $greeting = "Hello", string $punctuation = "!"): string
{
    return "$greeting, $name$punctuation";
}

echo greet("Kai"), "\n";
echo greet("Kai", "Good evening"), "\n";
echo greet("Kai", "Hi", "?"), "\n";
Output
Hello, Kai!
Good evening, Kai!
Hi, Kai?

Defaults must be constant expressions — literals, constants, arrays, enum cases or new objects — not function calls.

Named arguments

Since PHP 8.0 you can pass arguments by parameter name. They can come in any order, and you can skip optional parameters you don't want to change:

PHP
<?php

function book(string $city, int $nights, int $guests = 1, bool $breakfast = false): string
{
    return "$city: $nights nights, $guests guest(s)" . ($breakfast ? ", breakfast" : "");
}

echo book("Lisbon", 3), "\n";
echo book("Kyoto", nights: 5, breakfast: true), "\n";
echo book(guests: 4, city: "Rome", nights: 2), "\n";

echo str_pad("7", length: 3, pad_string: "0", pad_type: STR_PAD_LEFT), "\n";
Output
Lisbon: 3 nights, 1 guest(s)
Kyoto: 5 nights, 1 guest(s), breakfast
Rome: 2 nights, 4 guest(s)
007

Named arguments shine for boolean flags and long parameter lists: book("Kyoto", 5, 1, true) says nothing about what true means; breakfast: true does. They work with built-in functions too. The flip side is that renaming a parameter becomes a breaking change for callers.

Errors in calls

PHP
<?php

function area(float $width, float $height): float
{
    return $width * $height;
}

echo area(3), "\n";
Output
Fatal error: Uncaught ArgumentCountError: Too few arguments to function area(), 1 passed in main.php on line 8 and exactly 2 expected in main.php:3
Stack trace:
#0 main.php(8): area(3.0)
#1 {main}
  thrown in main.php on line 3

Passing too many arguments to a user function is silently allowed (the extras are ignored), but named arguments that don't exist are an error.

Variadic parameters

...$name as the last parameter collects any remaining arguments into an array:

PHP
<?php

function logMessage(string $level, string ...$parts): void
{
    echo "[$level] ", implode(" ", $parts), "\n";
}

function total(int|float ...$amounts): int|float
{
    return array_sum($amounts);
}

logMessage("INFO", "Server", "started");
logMessage("WARN", "Disk", "at", "91%");
echo total(), " ", total(5), " ", total(1, 2.5, 3), "\n";
echo total(...[10, 20, 30]), "\n";
Output
[INFO] Server started
[WARN] Disk at 91%
0 5 6.5
60

Passing by value

By default, a function receives a copy of each argument (for arrays and scalars). Changing the parameter doesn't affect the caller's variable:

PHP
<?php

function addBonus(int $score): int
{
    $score += 5;
    return $score;
}

function addItem(array $list): array
{
    $list[] = "extra";
    return $list;
}

$score = 10;
$newScore = addBonus($score);
echo "$score $newScore\n";

$items = ["a", "b"];
$more = addItem($items);
echo count($items), " ", count($more), "\n";
Output
10 15
2 3

Objects behave differently: the function receives a handle to the same object, so changes to its properties are visible to the caller (lesson 33).

Passing by reference

Prefixing a parameter with & passes the caller's variable itself, so the function can change it. Several built-in functions work this way — sort, array_push, preg_match's matches argument:

PHP
<?php

function addBonusInPlace(int &$score): void
{
    $score += 5;
}

function swap(mixed &$a, mixed &$b): void
{
    [$a, $b] = [$b, $a];
}

$score = 10;
addBonusInPlace($score);
echo $score, "\n";

$x = "left";
$y = "right";
swap($x, $y);
echo "$x $y\n";
Output
15
right left

References make data flow harder to follow, so prefer returning values. Reserve references for cases where modifying in place is the point, or where returning would be awkward.

Returning several values

Return an array and destructure it (lesson 26), or return an object when the result has a meaningful shape:

PHP
<?php

function stats(array $values): array
{
    return [
        'min' => min($values),
        'max' => max($values),
        'mean' => array_sum($values) / count($values),
    ];
}

['min' => $min, 'max' => $max, 'mean' => $mean] = stats([4, 9, 1, 7, 3]);
echo "min $min, max $max, mean $mean\n";
Output
min 1, max 9, mean 4.8

Try it yourself

Add an optional decimals parameter and call the function with named arguments.

Try it yourself · main.php
Edit the code, copy it into main.php, then run it with php main.php (PHP 8.5). How to install PHP
Output
1.61 km
42.2 km
3 mi