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 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";
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 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";
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 function area(float $width, float $height): float { return $width * $height; } echo area(3), "\n";
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 3Passing 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 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";
[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 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";
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 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";
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 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";
min 1, max 9, mean 4.8
Try it yourself
Add an optional decimals parameter and call the function with named arguments.
1.61 km 42.2 km 3 mi